我有一个Ant构建文件,它使用batchtest
junit来测试所有测试类。
假设我有一个班级
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
个内容。实际上我遇到的问题是 在本地环境中通过测试并在生产时失败 。
答案 0 :(得分:0)
我能看到工作的唯一可能方法是拥有<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 Files\Java\jdk1.7.0_25\jre\bin\java.exe' with arguments:
[junit] '-classpath'
...
[junit] 'org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner'
[junit] 'TestSimple'
[junit] 'methods=testOne'
...
[junit] Executing 'C:\Program Files\Java\jdk1.7.0_25\jre\bin\java.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
标记重定向到其他目录,或使用属性{{1更改输出文件的名称}}。那是因为报告文件名使用的是类的名称,而不是您正在运行的方法。这意味着第二次运行将覆盖第一次运行的报告。
在您的特定情况下,您可以对可以在同一JVM中运行的所有测试使用outfile
而不会出现问题,并添加<batchtest>
标记以避免运行有问题的测试。然后为每个有问题的测试添加特定的<exclude>
标记。
他们这样做是因为<test>
属性专门用于重新运行特定方法或运行速度太慢的单独测试。来自documentation:
在以下场景中,methods属性非常有用:
- 测试方法失败,您想重新运行测试方法 测试修复或在Java调试器下重新运行测试而不必 等待其他(可能是长时间运行的)测试方法 完成。
- 一个或多个测试方法的运行速度低于预期 并且你想在Java分析器下重新运行它们(没有 在运行探查器的过程中,其他测试方法正在进行中 执行)。
但就个人而言,来自遇到与之前相同问题的人,静态初始化程序很糟糕!我会尽快努力摆脱它们。引用@PeterNiederwieser,为每组测试设置一个新的JVM将使测试套件的运行速度非常慢!