使用 JUnit
配置 JUnit
要开始使用 JUnit,您需要将所需版本的 JUnit 添加到您的项目中:
<dependencies> [...] <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> [...] </dependencies>
这是开始所需的唯一步骤 - 您现在可以在测试源目录中创建测试(例如,src/test/java
)。
不同代的 JUnit 支持
Surefire 支持三代不同的 JUnit:JUnit 3.8.x、JUnit 4.x(串行提供程序)和 JUnit 4.7(具有并行支持的 junit-core 提供程序)。根据项目中的 JUnit 版本和配置参数(用于并行)选择提供程序。
JUnit 4.x 的升级检查
从 Surefire 2.7 版开始,选择运行哪些测试的算法发生了变化。从 2.7 开始,仅对所有版本的 JUnit 运行有效的 JUnit 测试,旧版本的插件也会运行满足命名约定的无效测试。
从 2.7 之前的 Surefire 版本升级时,可以使用 flag 运行构建-Dsurefire.junit4.upgradecheck
。这将执行检查并通知您不会使用此版本的 Surefire 运行的任何无效测试(并且构建失败)。这仅在升级时用作工具,以检查是否将运行所有预期的测试。这是一个过渡功能,将在未来版本的 Surefire 中删除。
提供者选择
如果未配置任何内容,Surefire 会通过以下算法检测要使用的 JUnit 版本:
if the JUnit 5 Platform Engine is present in the project use junit-platform if the JUnit version in the project >= 4.7 and the <<<parallel>>> configuration parameter has ANY value use junit47 provider if JUnit >= 4.0 is present use junit4 provider else use junit3.8.1
请注意,此算法的“else”部分也是常见问题解答:
您依赖于项目依赖项中存在的适当版本的 JUnit,否则 Surefire 可能会选择错误的提供程序。例如,如果您的一个依赖项引入了 JUnit 3.8.1,那么您就有风险选择 3.8.1 提供程序,它不支持注释或任何 4.x 特性。
使用mvn dependency:tree
POM 依赖排序和/或排除传递依赖来解决此问题。
手动指定提供者
您还可以通过将其作为依赖项添加到 Surefire 本身来手动强制特定提供程序:
<plugins> [...] <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M5</version> <dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> <version>3.0.0-M5</version> </dependency> </dependencies> </plugin> [...] </plugins>
使用此技术时,不会检查项目的类路径中是否存在正确的测试框架。未能添加正确的测试框架将导致构建失败。
并行运行测试
从 JUnit 4.7 开始,您可以并行运行测试。为此,您必须设置parallel
参数,并且可以更改threadCount
oruseUnlimitedThreads
属性。例如:
<plugins> [...] <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M5</version> <configuration> <parallel>methods</parallel> <threadCount>10</threadCount> </configuration> </plugin> [...] </plugins>
如果您的测试为该parallel
属性指定任何值并且您的项目使用 JUnit 4.7+,那么您的请求将被路由到使用 JUnit JUnitCore 测试运行器的并发 JUnit 提供者。
这对于可能具有高并发性的慢速测试特别有用。
从 Surefire 2.7 开始,不需要额外的依赖项即可使用完整的并行选项集。从 Surefire 2.16 开始,引入了新的线程数属性,threadCountSuites
即threadCountClasses
和threadCountMethods
。此外,新属性parallelTestsTimeoutInSeconds
和parallelTestsTimeoutForcedInSeconds
用于在超时后关闭并行执行,并且该属性parallel
指定新值。
另请参阅分叉选项和并行测试执行。
使用自定义侦听器和报告器
junit4 和 junit47 提供程序支持将自定义附加RunListeners
到您的测试。
您可以像这样配置多个自定义侦听器:
<dependencies> [...] <dependency> <groupId>your-junit-listener-artifact-groupid</groupId> <artifactId>your-junit-listener-artifact-artifactid</artifactId> <version>your-junit-listener-artifact-version</version> <scope>test</scope> </dependency> [...] </dependencies> [...] <plugins> [...] <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M5</version> <configuration> <properties> <property> <name>listener</name> <value>com.mycompany.MyResultListener,com.mycompany.MyResultListener2</value> </property> </properties> </configuration> </plugin> [...] </plugins>
有关 JUnit 的更多信息,请参阅JUnit 网站。
org.junit.runner.notification.RunListener
您可以在单独的测试工件your-junit-listener-artifact
中使用 scope=test 或在项目测试源代码中实现 JUnit 侦听器接口src/test/java
。您可以通过参数过滤测试工件,以dependenciesToScan
将其类加载到 surefire-junit* 提供程序的当前 ClassLoader 中。
由于 JUnit 4.12 线程安全监听器类应该被注释以org.junit.runner.notification.RunListener.ThreadSafe
避免在 JUnit 中不必要的锁。
使用安全管理器(仅限 JUnit3)
只要forkCount
不是 0 并且您使用 JUnit3,您就可以在启用 Java 安全管理器的情况下运行测试。安全管理器的类名必须作为系统属性变量发送给 JUnit3 提供者。
JUnit4 在内部使用与测试的安全管理器不兼容的机制,因此 Surefire 不支持这种使用 JUnit4 配置安全管理器的方法。
<plugins> [...] <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M5</version> <configuration> <systemPropertyVariables> <surefire.security.manager>java.lang.SecurityManager</surefire.security.manager> </systemPropertyVariables> </configuration> </plugin> [...] </plugins>
使用安全管理器(所有提供商)
或者,您可以定义一个策略文件,允许所有提供程序使用 Surefire 运行并使用argLine
参数和两个系统属性对其进行配置:
<plugins> [...] <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M5</version> <configuration> <argLine>-Djava.security.manager -Djava.security.policy=${basedir}/src/test/resources/java.policy</argLine> </configuration> </plugin> [...] </plugins>
这种解决方案的缺点是策略变化也会影响测试,这使得安全环境不太现实。
使用 JUnit 类别
JUnit 4.8 引入了类别的概念。您可以通过使用该groups
参数来使用 JUnit 类别。只要项目中的 JUnit 版本是 4.8 或更高,“groups”参数的存在就会自动让 Surefire 选择支持组的 junit47 提供程序。
<plugins> [...] <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M5</version> <configuration> <groups>com.mycompany.SlowTests</groups> </configuration> </plugin> [...] </plugins>
这将只执行那些用@Category(com.mycompany.SlowTests.class)
注解注解的测试和那些用@Category(com.mycompany.SlowerTests.class)
如果类/接口SlowerTests
是子类注解的测试SlowTests
:
public interface SlowTests{} public interface SlowerTests extends SlowTests{}
public class AppTest { @Test @Category(com.mycompany.SlowTests.class) public void testSlow() { System.out.println("slow"); } @Test @Category(com.mycompany.SlowerTests.class) public void testSlower() { System.out.println("slower"); } @Test @Category(com.cmycompany.FastTests.class) public void testSlow() { System.out.println("fast"); } }
@Category
注释也可以应用于类级别。
可以通过在参数中用逗号分隔多个类别来指定多个类别,groups
在这种情况下,将执行带有任何类别注释的测试。
有关 JUnit 的更多信息,请参阅JUnit 网站。
从 2.18.1 和 JUnit 4.12 版本开始,@Category
注释类型自动从超类继承,请参阅@java.lang.annotation.Inherited
. @Category
确保测试类继承与超类中出现的 JUnit 4.12 或更高版本的注释一起仍然有意义。