`

用 dbunit-maven-plugin 来管理你的测试数据

阅读更多

单元测试有人写过,也有人没做过,数据库的 dbunit 的用的人应该更少了,它可以用来给你做测试准备数据。一般我们做测试会在一个测试数据库中不停的测,自然会累积许多垃圾数据,给单元测试会造成不便,功能测试倒无太紧要。如果我们想在单元测试的时候有一份干净的数据,有个做法是搞个备用的数据库,测试前导到测试库的,或用某些数据库的导入导出功能。

这里我们来看 dbunit 怎么实现准备测试数据的,它可以用来导出数据库数据到数据文件中,从数据文件中导入干净的数据到数据库中,比较数据库与数据文件、或增量的插入记录等等。

dbunit 最初为 ant 提供了 antask,当然可以编程使用,如今 maven 大行其道,所以也就有了 maven 的 dbunit 插件,相似功能的插件有两个:

1. dbunit-maven-plugin
2. maven-dbunit-plugin

就是 maven 和 dbunit 倒了一下,别晕了,第二个似乎提供了更多的 goal,但运行 mvn dbunit:xxxx,指向的是第一个 dbunit-maven-plugin,看来第一个要正统些。本文也就介绍下dbunit-maven-plugin 的用法,测试数据库是 MySql。

看我们的 pom.xml 文件:

<project xmlns="<a href="http://maven.apache.org/POM/4.0.0" class="broken_link">http://maven.apache.org/POM/4.0.0</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"
    xsi:schemaLocation="<a href="http://maven.apache.org/POM/4.0.0" class="broken_link">http://maven.apache.org/POM/4.0.0</a> <a href="http://maven.apache.org/maven-v4_0_0.xsd">http://maven.apache.org/maven-v4_0_0.xsd</a>">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cc.unmi</groupId>
    <artifactId>testdbunit</artifactId>
    <name>TestDbuni</name>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>dbunit-maven-plugin</artifactId>
                <version>1.0-beta-3</version>
                <configuration>
                    <driver>com.mysql.jdbc.Driver</driver>
                    <url>jdbc:mysql://localhost/wptest?zeroDateTimeBehavior=convertToNull</url>
                    <username>root</username>
                    <password></password>
                    <dataTypeFactoryName>org.dbunit.ext.mysql.MySqlDataTypeFactory</dataTypeFactoryName>
                    <metadataHandlerName>org.dbunit.ext.mysql.MySqlMetadataHandler</metadataHandlerName>
                    <encoding>utf-8</encoding>
                    <src>target/dbunit/export.xml</src><!--compare 和 operation 要用到它 -->
                    <type>CLEAN_INSERT</type><!--operation 要用到它-->
                </configuration>
 
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.13</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>
 dbunit-maven-plugin 有四个 goal,分别是:

dbunit:compare 比较数据库与数据文件中的内容,相同则提示成功,不同则报异常
dbunit:export 导出数据库内容到数据文件中,默认是 xml 格式的数据
dbunit:help 看帮助的,要看 goal 的更详细的帮助可用:mvn dbunit:help -Ddetail=true -Dgoal=<goal-name>
dbunit:operation 可用来执行数据库操作,如 插入、清除数据,清除并插件数据等。用的多的应该是 CLEAN_INSERT,可得到一份干净的数据库。

上面的 pom.xml 是一个基本的配置,未指定的会使用默认值,例如导出数据的目的地是 <dest>target/dbunit/export.xml</dest>,点击每个 goal 的链接可以看到可以加到 <configuration> 节点中更多的配置项。

好了,现在有了 pom.xml 文件就可以用来执行相应的 goal 了,在命令行下进到这个 pom.xml 所在的目录中:

执行 mvn dbunit:export 你会看到生成了一个 target/dbunit/export.xml,包含了库中所有表的数据。

执行 mvn dbunit:compare 会将 <src> 指定的数据文件与数据库内容对比,相同则提示成功,不同就会报异常,由于我们上面指定的源文件是刚刚导出的 target/dbunit/export.xml,所以比较是成功的。

现在把数据库清空掉,然后执行 mvn dbunit:operation 后,你会发现数据库中的内容又原来的一样,是因为这个命令把数据文件 <src> 指示的 target/dbunit/export.xml 的数据导入到了数据库中。其实在执行 CLEAN_INSERT 时会先把数据库中的数据清理掉的。

dbunit:operation goal 的 type 取值有:UPDATE, INSERT, DELETE, DELETE_ALL, REFRESH, CLEAN_INSERT, MSSQL_INSERT, MSSQL_REFRESH, MSSQL_CLEAN_INSERT,你可以尝试一下其他值产生的效果,有些很容易理解用途的。

可能出现的异常,比如当执行 mvn dbunit:export 有 ERROR 时,请加上 -e 参数执行,mvn dbunit:export -e (要是执行 mvn dbunit:export -X 会有更多的信息)你将会看到详细的异常栈。例如碰到:

Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

就应该知道是驱动没找到,只要加到对 MySql 驱动的依赖就行。

你要是看到:

Caused by: java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column 8 to TIMESTAMP.

Caused by: java.sql.SQLException: Value '[B@297ffb' can not be represented as java.sql.Timestamp

这样的错误,那要请为你的 MySql jdbc 链接字符串加上属 zeroDateTimeBehavior=convertToNull。关于 MySql 的属性请参考文章下端列出的链接。

然而,有时候我们并不会直接去呼叫 dbunit:export 这样的 goal,我们会在某个 phase 之后来执行这个 goal,以 dbunit:export 为例,那就要在 pom.xml 中的 dbunit-maven-plugin 插件配置中加上:

<executions>
    <execution>
        <phase>process-test-classes</phase>
        <goals>
            <goal>operation</goal>
        </goals>
        <!-- specific configurations 我们可以在这里指定不同的配置-->
        <configuration>
            <format>xml</format>
            <src>src/export.xml</src>
            <type>CLEAN_INSERT</type>
        </configuration>
    </execution>
</executions>
 因为 phase 也是按顺序执行的,这里设置的 goal 是 process-test-classes,所以当我们在执行 mvn process-test-classes 后会调用这个 dbunit:operation goal。而当我们执行 mvn test 时,会发现这个 dbunit:operation 会在 test 之前执行,这能也就能为我们准备好单元测试的数据了,不会因为小动了下数据库而让 test 全线告错。

对于另外两个 goal,dbunit:compare 和 dbunit:export 也可以采用类似的配置,让某个 phase 来调用。

最后,留意下每个 goal 的所有配置以及相应的默认值,比如在执行 dbunit:export 时可以用 <schema> 指定导出哪些表,再严格点可以用

tables>
    <table>
        <name>wp_users</name>
        <name>wp_posts</name>
    </table>
</tables>
 指定导出某些特定的表。
分享到:
评论
1 楼 fealenyoung 2014-04-29  
class App {

}

相关推荐

Global site tag (gtag.js) - Google Analytics