在jUnit 4.x中执行Suite之前和之后的挂钩
我正在尝试使用jUnit 4.4执行一组集成测试的设置和拆卸。拆卸需要可靠地运行。我在使用TestNG时遇到其他问题,因此我希望移植回jUnit。在运行任何测试之前以及在完成所有测试之后,可以使用哪些挂钩执行?
注意:我们正在使用Maven 2进行构建。我已经尝试过使用maven的pre-
和post-integration-test
阶段,但是,如果测试失败,则maven停止并且不运行post-integration-test
,这没有帮助。
解决方案
回答
据我所知,在JUnit中没有执行此操作的机制,但是我们可以尝试对Suite进行子类化,并使用提供钩子的版本覆盖run()方法。
回答
使用注释,我们可以执行以下操作:
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() { } }
回答
我认为获得想要的功能的唯一方法是做类似的事情
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() {} }
我在eclipse中使用类似的东西,所以我不确定它在该环境之外的便携性
回答
是的,在测试套件中进行任何测试之前和之后,都可以可靠地运行设置和拆卸方法。让我用代码演示:
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"); } }
因此,Test1类看起来像:
package com.test; import org.junit.Test; public class Test1 { @Test public void test1() { System.out.println("test1"); } }
...我们可以想象Test2看起来很相似。如果运行TestSuite,我们将获得:
setting up test1 test2 tearing down
因此,我们可以看到设置/拆卸仅分别在所有测试之前和之后运行。
要点:仅当我们运行测试套件,而不是将Test1和Test2作为单独的JUnit测试运行时,此方法才有效。我们提到我们正在使用maven,并且maven surefire插件喜欢单独运行测试,而不是套件的一部分。在这种情况下,我建议创建一个每个测试类都可以扩展的超类。然后,超类包含带注释的@BeforeClass和@AfterClass方法。尽管不如上面的方法那么干净,但我认为它会为我们工作。
至于失败测试的问题,我们可以设置maven.test.error.ignore,以便在失败测试中继续构建。不建议我们将其作为持续的实践,但是在所有测试通过之前,它应该可以使我们正常运行。有关更多详细信息,请参见maven surefire文档。
回答
在这里,我们
- 升级到JUnit 4.5,
- 编写注释以标记需要工作服务的每个测试类或者方法,
- 为每个注释编写了处理程序,其中包含静态方法以实现服务的设置和拆卸,
- 扩展了通常的Runner以在测试上定位注释,并在适当的位置将静态处理程序方法添加到测试执行链中。
回答
由于maven-surefire-plugin不会先运行套件类,而是将套件和测试类相同,因此我们可以按以下方式配置插件,以仅启用套件类并禁用所有测试。 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>
回答
至于"注意:我们正在使用maven 2进行构建。我已经尝试过使用maven的集成前和集成后测试阶段,但是,如果测试失败,则maven会停止并且不会运行集成后测试,这会导致没有帮助。"
我们可以尝试使用故障安全插件,我认为它具有确保清除的功能,而无论安装程序或者中间阶段的状态如何