我有一个 Ant 构建文件,它使用 junit 的batchtest
来测试所有测试类。
假设我有一个类
class MyTest{
@BeforeClass
public static void setUpBeforeClass(){
//some stuff
}
@Test
public void test1(){
}
@Test
public void test2(){
}
}
我知道 JUnit 为每个测试方法创建了一个MyTest
类的新实例,但我想要的是应该为每个测试方法创建一个新的 VM。我希望每个测试方法都在单独的 VM 中运行,并希望类加载器为每个测试方法再次加载MyTest
。这可能吗?
我尝试阅读文档并尝试了以下解决方案:
<junit fork="yes" reloading="true" forkmode="perTest">
<batchtest>
</batchtest>
</junit>
但是,即使对我的每个测试方法都使用这些选项,setUpBeforeClass
方法也只调用一次。我做错了什么吗?
编辑:
我为什么要这样做?
我的测试方法是使用一些使用static
东西的协作者,我希望在每种方法上清除static
的东西。实际上,我面临着一个测试在本地环境中通过而在生产中失败的问题。
我可以看到工作的唯一可能方法是拥有多个<test>
元素实例。
这样做的问题是,您必须为每个<test>
元素指定要运行的方法。我创建了一个测试类,其中包含一个静态初始值设定项和两个测试。通过以下<junit>
任务,我能够做你想做的事:
<junit fork="yes">
<classpath>
<path refid="classpath" />
</classpath>
<formatter type="xml"/>
<test name="TestSimple" methods="testOne" toDir="firstRun" />
<test name="TestSimple" methods="testTwo" toDir="secondRun" />
</junit>
从我从构建日志中得到的信息来看,很明显它们在两个不同的 JVM 中运行:
test:
...
[junit] Executing 'C:Program FilesJavajdk1.7.0_25jrebinjava.exe' with arguments:
[junit] '-classpath'
...
[junit] 'org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner'
[junit] 'TestSimple'
[junit] 'methods=testOne'
...
[junit] Executing 'C:Program FilesJavajdk1.7.0_25jrebinjava.exe' with arguments:
[junit] '-classpath'
...
[junit] 'org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner'
[junit] 'TestSimple'
[junit] 'methods=testTwo'
...
[junit] Test TestSimple FAILED
我还在每个测试的报告中看到了我放入静态初始值设定项中的System.out
语句。
这里重要的细节是,您必须<test>
使用属性 toDir
将其报告重定向到不同的目录,或者使用属性 outfile
更改输出文件的名称。这是因为报表文件名使用类的名称,而不是您正在运行的方法。这意味着第二次运行将覆盖第一次运行的报告。
在您的特定情况下,您可以对所有可以在同一 JVM 中运行而不会出现问题的测试使用<batchtest>
,并添加 <exclude>
标记以避免运行有问题的测试。然后为每个有问题的测试添加特定的<test>
标记。
他们这样做是因为 methods
属性专门设计用于重新运行运行速度太慢的特定方法或单独的测试。从文档中:
方法属性在以下情况下很有用:
测试方法
- 失败,您希望重新运行测试方法以 测试修复程序或在 Java 调试器下重新运行测试,而无需 等待其他(可能长时间运行的(测试方法 完成。
- 一个或多个测试方法的运行速度比预期慢 并且您希望在 Java 探查器下重新运行它们(没有 在其他测试方法运行时运行探查器的开销 已执行(。
但就个人而言,并且来自一个以前遇到过与您相同问题的人,静态初始值设定项很糟糕!我会非常努力地尽快摆脱它们。引用@PeterNiederwieser的话,为每组测试配备一个新的 JVM 会使运行测试套件的速度非常慢!