并行 JUnit 测试不执行关闭挂钩
Posted
技术标签:
【中文标题】并行 JUnit 测试不执行关闭挂钩【英文标题】:Parallel JUnit tests don't execute shutdown hook 【发布时间】:2015-12-27 13:14:37 【问题描述】:我正在使用 Maven 在并行类中运行多个 JUnit 测试。我有清理所有 JUnit 测试运行后需要执行的任务。为了处理这种清理,我在一些测试中添加了一个关闭挂钩。当我 不 并行运行时,关闭挂钩正确执行,但是当我并行运行时,我看不到关闭挂钩的输出(参见示例)。有什么我做错了吗?在 JUnit 测试中并行执行时,JVM 是否使用System.exit
退出?
根据 Surfire 文档文档,并行线程在同一个进程中执行,所以我希望 Runtime.getRuntime 是同一个进程,即使它在不同的测试和线程之间被调用。 Maven Surfire Plugin - Fork Options and Parallel Test Execution
使用并行选项要记住的重要一点是: 并发发生在同一个 JVM 进程中。这是有效的 内存和执行时间方面,但你可能更容易受到攻击 朝向比赛条件或其他意想不到且难以重现的情况 行为。
这是我的单元测试中的一个示例:
@Test
public void test()
Runtime.getRuntime().addShutdownHook(new Thread()
@Override
public void run()
System.out.println("Test clean up triggered");
);
这是我的 pom 的相关部分:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>10</threadCount>
</configuration>
</plugin>
已编辑:
当我在 @BeforeClass
方法中添加关闭挂钩时,问题得到解决。当我在@Test
方法中添加它时,我遇到了问题。我希望能够随时添加钩子。
【问题讨论】:
【参考方案1】:实际上调用了您的关闭挂钩,我认为问题来自与 maven 的关闭挂钩相关的 system.out.println
调用。
直接用Eclipse测试,我有输出:
Test clean up triggered
并尝试稍微不同的测试版本:
@Test
public void test()
System.out.println("Testing");
Runtime.getRuntime().addShutdownHook(new Thread()
@Override
public void run()
try
Files.createFile(Paths.get("test1"));
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
);
assertTrue(true);
我可以在我的director 的根目录中看到调用mvn clean test
后创建的文件“test1”
测试:
openjdk 版本“1.8.0_121” Junit 4.12 Maven 3.3.9 Maven surefire-plugin 2.17【讨论】:
我的问题的关键是在 Maven 中并行运行测试,并在 @BeforeClass 中设置了关闭挂钩。当我复制问题时,它是一个更大项目的一部分。我刚刚建立了一个快速 2 测试项目,但问题没有重现。我不知道这是否仍然重现,因为问题是一段时间前我无法确定是否执行了错误修复,或者我的大型项目中是否存在其他问题。 @JeredM 上面的示例仅用于演示目的。在@BeforeClass
方法中初始化关闭挂钩确实更明智。现在,使用上面列出的设置,我尝试了各种组合,我遇到的唯一失败是由于无序测试(试图在声明之前删除钩子,这是预期的错误)。出于好奇,您是否还有用于解决此故障的设置?
我没有那个设置了:(以上是关于并行 JUnit 测试不执行关闭挂钩的主要内容,如果未能解决你的问题,请参考以下文章
带有 @Suite 注释的 Junit5 测试套件不使用 mvn test 命令执行测试
JUnit 和 Surefire 并行测试 - ForkCount 和 ThreadCount