Java jUnit 4.x 中的 Suite 执行挂钩之前和之后

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/82949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:05:39  来源:igfitidea点击:

Before and After Suite execution hook in jUnit 4.x

javatestingjunitintegration-testing

提问by sblundy

I'm trying to preform setup and teardown for a set of integration tests, using jUnit 4.4 to execute the tests. The teardown needs to be run reliably. I'm having other problems with TestNG, so I'm looking to port back to jUnit. What hooks are available for execution before any tests are run and after all tests have completed?

我正在尝试为一组集成测试执行设置和拆卸,使用 jUnit 4.4 来执行测试。拆解需要可靠地运行。我在使用 TestNG 时遇到了其他问题,所以我希望移植回 jUnit。在运行任何测试之前和完成所有测试之后,哪些挂钩可用于执行?

Note: we're using maven 2 for our build. I've tried using maven's pre-& post-integration-testphases, but, if a test fails, maven stops and doesn't run post-integration-test, which is no help.

注意:我们使用 maven 2 进行构建。我试过使用 maven 的pre-&post-integration-test阶段,但是,如果测试失败,maven 会停止并且不会运行post-integration-test,这无济于事。

回答by user15299

As far as I know there is no mechanism for doing this in JUnit, however you could try subclassing Suite and overriding the run() method with a version that does provide hooks.

据我所知,在 JUnit 中没有执行此操作的机制,但是您可以尝试子类化 Suite 并使用提供挂钩的版本覆盖 run() 方法。

回答by Jroc

Using annotations, you can do something like this:

使用注释,您可以执行以下操作:

import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;

class SomethingUnitTest {
    @BeforeClass
    public static void runBeforeClass()
    {

    }

    @AfterClass
    public static void runAfterClass()
    {  

    }

    @Before  
    public void setUp()
    {

    }

    @After
    public void tearDown()
    {

    }

    @Test
    public void testSomethingOrOther()
    {

    }

}

回答by Jroc

The only way I think then to get the functionality you want would be to do something like

我认为然后获得您想要的功能的唯一方法是做类似的事情

import junit.framework.Test;  
import junit.framework.TestResult;  
import junit.framework.TestSuite;  

public class AllTests {  
    public static Test suite() {  
        TestSuite suite = new TestSuite("TestEverything");  
        //$JUnit-BEGIN$  
        suite.addTestSuite(TestOne.class);  
        suite.addTestSuite(TestTwo.class);  
        suite.addTestSuite(TestThree.class);  
        //$JUnit-END$  
     }  

     public static void main(String[] args)  
     {  
        AllTests test = new AllTests();  
        Test testCase = test.suite();  
        TestResult result = new TestResult();  
        setUp();  
        testCase.run(result);  
        tearDown();  
     }  
     public void setUp() {}  
     public void tearDown() {}  
} 

I use something like this in eclipse, so I'm not sure how portable it is outside of that environment

我在 Eclipse 中使用了这样的东西,所以我不确定它在该环境之外的便携性如何

回答by Julie

Yes, it is possible to reliably run set up and tear down methods before and after any tests in a test suite. Let me demonstrate in code:

是的,可以在测试套件中的任何测试之前和之后可靠地运行设置和拆除方法。让我用代码来演示:

package com.test;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({Test1.class, Test2.class})
public class TestSuite {

    @BeforeClass
    public static void setUp() {
        System.out.println("setting up");
    }

    @AfterClass
    public static void tearDown() {
        System.out.println("tearing down");
    }

}

So your Test1 class would look something like:

所以你的 Test1 类看起来像:

package com.test;

import org.junit.Test;


public class Test1 {
    @Test
    public void test1() {
        System.out.println("test1");
    }

}

...and you can imagine that Test2 looks similar. If you ran TestSuite, you would get:

...你可以想象 Test2 看起来很相似。如果您运行 TestSuite,您将获得:

setting up
test1
test2
tearing down

So you can see that the set up/tear down only run before and after all tests, respectively.

所以你可以看到设置/拆卸只分别在所有测试之前和之后运行。

The catch: this only works if you're running the test suite, and not running Test1 and Test2 as individual JUnit tests. You mentioned you're using maven, and the maven surefire plugin likes to run tests individually, and not part of a suite. In this case, I would recommend creating a superclass that each test class extends. The superclass then contains the annotated @BeforeClass and @AfterClass methods. Although not quite as clean as the above method, I think it will work for you.

问题:这仅在您运行测试套件时有效,而不是将 Test1 和 Test2 作为单独的 JUnit 测试运行。您提到您正在使用 maven,并且 maven surefire 插件喜欢单独运行测试,而不是套件的一部分。在这种情况下,我建议创建一个每个测试类都扩展的超类。然后超类包含带注释的@BeforeClass 和@AfterClass 方法。虽然不像上述方法那么干净,但我认为它对你有用。

As for the problem with failed tests, you can set maven.test.error.ignore so that the build continues on failed tests. This is not recommended as a continuing practice, but it should get you functioning until all of your tests pass. For more detail, see the maven surefire documentation.

至于测试失败的问题,您可以设置 maven.test.error.ignore 以便构建在失败的测试上继续。不建议将此作为持续实践,但它应该可以让您正常工作,直到您的所有测试都通过为止。有关更多详细信息,请参阅maven surefire 文档

回答by Julie

Here, we

在这里,我们

  • upgraded to JUnit 4.5,
  • wrote annotations to tag each test class or method which needed a working service,
  • wrote handlers for each annotation which contained static methods to implement the setup and teardown of the service,
  • extended the usual Runner to locate the annotations on tests, adding the static handler methods into the test execution chain at the appropriate points.
  • 升级到 JUnit 4.5,
  • 编写注释来标记需要工作服务的每个测试类或方法,
  • 为每个包含静态方法的注释编写处理程序,以实现服务的设置和拆除,
  • 扩展了通常的 Runner 以定位测试上的注释,在适当的点将静态处理程序方法添加到测试执行链中。

回答by Anurag Sharma

Since maven-surefire-plugin does not run Suite class first but treats suite and test classes same, so we can configure plugin as below to enable only suite classes and disable all the tests. Suite will run all the tests.

由于 maven-surefire-plugin 不会首先运行 Suite 类而是将套件和测试类视为相同,因此我们可以如下配置插件以仅启用套件类并禁用所有测试。Suite 将运行所有测试。

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.5</version>
            <configuration>
                <includes>
                    <include>**/*Suite.java</include>
                </includes>
                <excludes>
                    <exclude>**/*Test.java</exclude>
                    <exclude>**/*Tests.java</exclude>
                </excludes>
            </configuration>
        </plugin>

回答by Binod Pant

As for "Note: we're using maven 2 for our build. I've tried using maven's pre- & post-integration-test phases, but, if a test fails, maven stops and doesn't run post-integration-test, which is no help."

至于“注意:我们正在使用 maven 2 进行构建。我已经尝试使用 maven 的 pre-&post-integration-test 阶段,但是,如果测试失败,maven 会停止并且不会运行 post-integration-test ,这没有帮助。”

you can try the failsafe-plugin instead, I think it has the facility to ensure cleanup occurs regardless of setup or intermediate stage status

您可以尝试使用故障安全插件,我认为无论设置或中间阶段状态如何,它都可以确保进行清理

回答by christophe blin

Provided that all your tests may extend a "technical" class and are in the same package, you can do a little trick :

假设您的所有测试都可以扩展“技术”类并且在同一个包中,您可以做一个小技巧:

public class AbstractTest {
  private static int nbTests = listClassesIn(<package>).size();
  private static int curTest = 0;

  @BeforeClass
  public static void incCurTest() { curTest++; }

  @AfterClass
  public static void closeTestSuite() {
      if (curTest == nbTests) { /*cleaning*/ }             
  }
}

public class Test1 extends AbstractTest {
   @Test
   public void check() {}
}
public class Test2 extends AbstractTest {
   @Test
   public void check() {}
}

Be aware that this solution has a lot of drawbacks :

请注意,此解决方案有很多缺点:

  • must execute all tests of the package
  • must subclass a "techincal" class
  • you can not use @BeforeClass and @AfterClass inside subclasses
  • if you execute only one test in the package, cleaning is not done
  • ...
  • 必须执行包的所有测试
  • 必须是“技术”类的子类
  • 你不能在子类中使用 @BeforeClass 和 @AfterClass
  • 如果您只在包中执行一项测试,则不会进行清洁
  • ...

For information: listClassesIn() => How do you find all subclasses of a given class in Java?

有关信息: listClassesIn() =>如何在 Java 中找到给定类的所有子类?

回答by Martin Vysny

A colleague of mine suggested the following: you can use a custom RunListener and implement the testRunFinished() method: http://junit.sourceforge.net/javadoc/org/junit/runner/notification/RunListener.html#testRunFinished(org.junit.runner.Result)

我的一位同事建议如下:您可以使用自定义 RunListener 并实现 testRunFinished() 方法:http://junit.sourceforge.net/javadoc/org/junit/runner/notification/RunListener.html#testRunFinished(org . junit.runner.Result)

To register the RunListener just configure the surefire plugin as follows: http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.htmlsection "Using custom listeners and reporters"

要注册 RunListener,只需按如下方式配置 surefire 插件:http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html 部分“使用自定义侦听器和报告器”

This configuration should also be picked by the failsafe plugin. This solution is great because you don't have to specify Suites, lookup test classes or any of this stuff - it lets Maven to do its magic, waiting for all tests to finish.

此配置也应由故障安全插件选择。这个解决方案很棒,因为您不必指定套件、查找测试类或任何这些东西——它让 Maven 发挥它的魔力,等待所有测试完成。