简体   繁体   English

运行每个测试 <batchtest> 在Ant中使用JUnit的单独VM中

[英]Run each test of <batchtest> in separate VM using JUnit in Ant

I have a Ant build file which uses batchtest of junit to test all the test classes. 我有一个Ant构建文件,它使用batchtest的junit来测试所有的测试类。

Suppose I have a class 假设我有一堂课

class MyTest{
    @BeforeClass
    public static void setUpBeforeClass(){
       //some stuff
    }

    @Test
    public void test1(){
    }

    @Test
    public void test2(){
    }
}

I know that JUnit creates a new instance of MyTest class for each test method, but what I want is that a new VM should be created for each test method. 我知道JUnit为每个测试方法创建了一个新的MyTest类实例,但我想要的是应该为每个测试方法创建一个新的VM。 I want each test method to rum in a separate VM and want classloader to load MyTest again for each test method. 我希望每个测试方法都在单独的VM中进行朗读,并希望类加载器为每个测试方法再次加载MyTest Is that possible? 那可能吗?

I have tried to read the documentation and tried this solution: 我试过阅读文档并尝试了这个解决方案:

<junit fork="yes" reloading="true" forkmode="perTest">
    <batchtest>
    </batchtest>
</junit>

But even after using these options for each of my test method the setUpBeforeClass method is called only once. 但即使在我的每个测试方法中使用这些选项之后, setUpBeforeClass方法也只被调用一次。 Am I doing something wrong? 难道我做错了什么?

EDIT: 编辑:

Why do I want to do that? 我为什么要那样做?

My test methods are using some collaborators that use static stuff and I want that static stuff to be cleared on every method. 我的测试方法是使用一些使用static内容的协作者,我希望在每个方法上清除static内容。 Actually I am facing an issue in which tests pass at local environment and fail at production . 实际上我面临的问题是测试在本地环境中通过而在生产中失败

The only possible way I can see that working is to have multiple instances of <test> elements. 我能看到工作的唯一可能方法是拥有多个<test>元素实例。

The problem with that is that you have to specify for each <test> element what methods you want to run. 问题是您必须为每个<test>元素指定要运行的方法。 I created a single test class that have a static initializer and two tests in it. 我创建了一个测试类,它有一个静态初始化程序和两个测试。 With the following <junit> task I was able to do what you want: 通过以下<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>

From what I get from the build logs, it's clear that they ran in two different JVMs: 根据我从构建日志中获得的内容,很明显它们运行在两个不同的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

I also see the System.out statement that I put in the static initializer in each test's report. 我还看到了我在每个测试报告中放入静态初始化程序的System.out语句。

The important detail here is that you have to make each <test> tag redirect their report to a different directory, using the attribute toDir or change the name of the output file using the attribute outfile . 这里的重要细节是,您必须使用属性toDir将每个<test>标记重定向到不同的目录,或使用属性outfile更改输出文件的名称。 That's because the report file name uses the name of the class and not the method you're running. 那是因为报告文件名使用的是类的名称,而不是您正在运行的方法。 Which means the second run will overwrite the first run's report. 这意味着第二次运行将覆盖第一次运行的报告。

In your specific case, you could use a <batchtest> to all tests that can run in the same JVM without problems and add an <exclude> tag to avoid running the problematic tests. 在您的特定情况下,您可以将<batchtest>用于可以在同一JVM中无问题地运行的所有测试,并添加<exclude>标记以避免运行有问题的测试。 Then add a specific <test> tag for each problematic test. 然后为每个有问题的测试添加特定的<test>标记。

They do that because the methods attribute is specifically designed to re-run specific methods or separate tests that are running too slow. 他们这样做是因为methods属性专门用于重新运行特定方法或运行速度太慢的单独测试。 From the documentation : 文档

The methods attribute can be useful in the following scenarios: methods属性在以下场景中非常有用:

  • A test method has failed and you want to re-run the test method to test a fix or re-run the test under the Java debugger without having to wait for the other (possibly long running) test methods to complete. 测试方法失败,您希望重新运行测试方法以测试修复或在Java调试器下重新运行测试,而无需等待其他(可能是长时间运行的)测试方法完成。
  • One or more test methods are running slower than expected and you want to re-run them under a Java profiler (without the overhead of running the profiler whilst other test methods are being executed). 一个或多个测试方法的运行速度比预期慢,并且您希望在Java分析器下重新运行它们(没有运行探查器的开销,而其他测试方法正在执行)。

But personally, and coming from a person that ran into the same problem as you before, static initializers suck! 但就个人而言,来自一个遇到与之前相同问题的人,静态初始化程序很糟糕! I would try really hard to get rid of them as soon as possible. 我会尽快努力摆脱它们。 And to quote @PeterNiederwieser, having a new JVM for each set of tests will make running your test suite very slow! 引用@PeterNiederwieser,为每组测试创建一个新的JVM将使您的测试套件运行速度非常慢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM