account-captcha的POM配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>account-captcha</artifactId>
<name>Account Captcha</name>
<properties>
<kaptcha.version>2.3</kaptcha.version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.code.kaptcha</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>sonatype-forge</id>
<name>Sonatype Forge</name>
<url>http://repository.sonatype.org/content/groups/forge/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
对上面的配置进行解释:
1、Kaptcha是一个用来生成验证码 (Captcha) 的开源类库,其主页:http://code.google.com/p/kaptcha
2、Kaptcha依赖还有一个classifier元素,其值为jdk5,Kaptcha针对1.5和1.4提供了不同的分发包
3、POM的最后声明了Sonatype Forge这一公共仓库,这是因为Kaptcha并没有上传到中央仓库,我们可以从Sonatype Forge仓库,或者直接将Kaptcha上传到自己的仓库中
4、如果配置了nexus,并且配置了镜像,配置这个仓库就不会起作用了,需要下载该包然后上传到nexux上去
maven-surefire-plugin简介
1、Maven本身并不是一个单元测试框架
2、Java世界中主流的单元测试框架为JUnit(http://www.junit.org/)和TestNG(http://testng.org/)
3、Maven所做的只是在构建执行到特定生命周期阶段的时候,通过插件来执行JUnit或者TestNG的测试用例
4、可称maven-surefire-plugin为测试运行器(Test Runner)
5、这个插件可以很好地兼容JUnit3、JUnit4以及TestNG
default生命周期的test阶段
这个test阶段被定义为 "使用单元测试框架运行测试"
我们知道,生命周期阶段需要绑定到某个插件的目标才能真正的工作
test阶段正式与maven-surefire-plugin的test目标相绑定了,这是一个内置的绑定
maven-surefire-plugin的test目标
在默认情况下,maven-surefire-plugin的test目标会自动执行测试源码路径(默认为src/test/java/)下所有符合一组命名模式的测试类,这组模式为:
n **/Test*.java:任何子目录下所有命名以Test开头的Java类
n **/*Test.java:任何子目录下所有命名以Test结尾的Java类
n **/*TestCase.java:任何子目录下所有命名以TestCase结尾的Java类
只要将测试类按上述模式命名,Maven就能自动运行它们,用户也就不再需要定义测试几何(TestSuite)来聚合测试用例 (TestCase) 关于模式需要注意的是,以Tests结尾的测试类是不会得以自动执行的
有时候需要跳过测试
1、我敢保证这次改动不会导致任何测试失败
2、测试运行太耗时了,暂时跳过一下
3、有持续集成服务跑所有测试呢,我本地就不执行啦
在大部分情况下,这些想法都是不对的,任何改动都要交给测试去验证,测试运行耗时过长应该考虑优化测试,更不要完全依赖持续集成服务来报告错误,测试错误应该尽早在尽小范围内发现,并及时修复
通过命令行方式跳过测试
mvn package -DskipTests
在POM中配置maven-surfire-plugin插件的属性,来跳过测试(不推荐)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
通过命令行的方式,即跳过测试代码的编译又跳过测试运行(不推荐)
mvn package -Dmaven.test.skip=true
参数maven.test.skip同时控制了maven-compiler-plugin和maven-surefire-plugin两个插件的行为,测试代码编译跳过了,测试运行也跳过了
通过POM配置,即跳过测试代码的编译又跳过测试运行(不推荐)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
实际上maven-compiler-plugin的testCompile目标和maven-surefire-plugin的test目标都提供了一个参数skip用来跳过测试编译和测试运行,而这个参数对应的命令行表达式为maven.test.skip
反复运行单个测试用例是日常开发中很常见的行为
例如,项目代码中有一个失败的测试用例,开发人员就会想要再次运行这个测试以获得详细的错误报告,在修复该测试的过程中,开发人员也会反复运行它,已确认修复代码是正确的。如果仅仅为了一个失败的测试用例而反复运行所有测试,未免太浪费时间了,当项目中测试的数目比较大的时候,这种浪费尤为明显
maven-surefire-plugin提供了一个test参数
这个参数让Maven用户能够在命令行指定要运行的测试用例
例如,如果只想运行account-captcha的RandomGeneratorTest,就可以使用如下命令:
mvn test -Dtest=RandomGeneratorTest
使用通配符*
mvn test -Dtest=Random*Test
星号可以匹配零个或多个字符,上述命令会运行项目中所有类名以Random开头、Test结尾的测试类
使用逗号指定多个测试用例
mvn test -Dtest=RandomGeneratorTest,AccountCaptchaServiceTest
test参数的值必须匹配一个或多个测试类
mvn test -Dtest
maven-surefire-plugin找不到任何匹配的测试类,就会报错并导致构建失败
使用-DfailIfNoTests=false配置
mvn test -Dtest -DfailIfNoTests=false
告知maven-surefire-plugin即使没有任何测试也不要报错,这也是另一种跳过测试的方法
从上面可以看到,test参数用户可以从命令行灵活地指定要运行的测试类,可惜的是maven-surefire-plugin并没有提供任何参数支持用户从命令行跳过指定的测试类,好在用户可以通过POM中配置maven-surefire-plugin排除特定的测试类
自动运行以Tests结尾的测试类
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<include>**/*Tests.java</include>
</configuration>
</plugin>
排除运行测试类
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<excludes>
<exclude>**/*ServiceTest.java</exclude>
<exclude>**/TempDaoTest.java</exclude>
</excludes>
</configuration>
</plugin>
测试报告
除了基本的命令行输出,Maven用户可以使用maven-surefire-plugin等插件以文件的形式生成更丰富的测试报告
基本的测试报告
默认情况下,maven-surefire-plugin会在项目的target/surefire-reports目录下生成两种格式的错误报告:
1、简单文本格式
2、JUnit兼容的XML格式
测试覆盖率报告
测试覆盖率是衡量项目代码质量的一个重要的参考指标。Cobertura是一个优秀的开源测试覆盖率统计工具 (详见http://cobertura.sourceforge.net/),Maven通过cobertura-maven-plugin与之集成,用户可以使用简单的命令为Maven项目生成测试覆盖率报告
例如可以在account-captcha目录下运行如下命令生成报告:
mvn cobertura:cobertura
接着会在target/site/cobertura/下生成一个index.xml文件,可以通过它查看测试覆盖率报告
重用测试代码
默认的打包行为是不会包含测试代码的,因此在使用外部依赖的时候,其构件一般都不会包含测试代码
然后,在项目内部重用某个模块的测试带是很常见的需求,可能某个底层模块的测试代码中包含了一些常用的测试工具类,或者一些高质量的测试基类供继承。这个时候Maven用户就需要通过配置maven-jar-plugin将测试类打包
打包测试代码
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<golas>
<goal>test-jar</goal>
</goals>
<execution>
</executions>
</plugin>
maven-jar-plugin有两个目标,分别是jar和test-jar
1、jar目标是通过Maven的内置绑定在default生命周期的package阶段运行,其行为就是对项目主代码进行打包
2、而test-jar并没有内置绑定,因此上述的插件配置显式声明该目标来打包测试代码
3、test-jar的默认绑定声明周期阶段为package
如何依赖测试包构件
<dependency>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-captcha</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>