jUnit 4.x의 Before and After Suite 실행 후크
테스트를 실행하기 위해 jUnit 4.4를 사용하여 통합 테스트 세트에 대한 설정 및 분해를 수행하려고합니다. 분해는 안정적으로 실행되어야합니다. TestNG에 다른 문제가 있으므로 jUnit으로 다시 포팅하려고합니다. 테스트가 실행되기 전과 모든 테스트가 완료된 후에 실행할 수있는 후크는 무엇입니까?
참고 : 우리는 빌드에 maven 2를 사용하고 있습니다. 나는 maven의 pre-& post-integration-test단계를 사용해 보았지만 테스트가 실패하면 maven이 중지되고 실행 post-integration-test되지 않으므로 도움이되지 않습니다.
예, 테스트 스위트에서 테스트 전후에 설정 및 해체 메소드를 안정적으로 실행할 수 있습니다. 코드로 보여 드리겠습니다.
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
따라서 설정 / 해체가 각각 모든 테스트 전후에만 실행되는 것을 볼 수 있습니다.
캐치 : 이것은 테스트 스위트를 실행하고 개별 JUnit 테스트로 Test1 및 Test2를 실행하지 않는 경우에만 작동합니다. 당신이 maven을 사용하고 있다고 언급했고 maven surefire 플러그인은 스위트의 일부가 아닌 개별적으로 테스트를 실행하는 것을 좋아합니다. 이 경우 각 테스트 클래스가 확장하는 수퍼 클래스를 만드는 것이 좋습니다. 그런 다음 수퍼 클래스에는 주석이 달린 @BeforeClass 및 @AfterClass 메서드가 포함됩니다. 위의 방법만큼 깨끗하지는 않지만 당신에게 효과적이라고 생각합니다.
실패한 테스트 문제의 경우 실패한 테스트에서 빌드가 계속되도록 maven.test.error.ignore를 설정할 수 있습니다. 이것은 지속적인 연습으로 권장되지 않지만 모든 테스트를 통과 할 때까지 기능을 발휘해야합니다. 자세한 내용은 maven surefire 문서를 참조하세요 .
제 동료는 다음을 제안했습니다. 사용자 정의 RunListener를 사용하고 testRunFinished () 메서드를 구현할 수 있습니다. http://junit.sourceforge.net/javadoc/org/junit/runner/notification/RunListener.html#testRunFinished(org. junit.runner.Result)
RunListener를 등록하려면 다음과 같이 surefire 플러그인을 구성하십시오. http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html 섹션 "사용자 정의 리스너 및 리포터 사용"
이 구성은 failsafe 플러그인에서도 선택해야합니다. 이 솔루션은 스위트, 룩업 테스트 클래스 또는 이와 같은 것들을 지정할 필요가 없기 때문에 훌륭합니다. Maven이 모든 테스트가 완료 될 때까지 기다릴 수 있도록합니다.
당신은 사용할 수 있습니다 JUnit을 4.9+에서 @ClassRule 주석 으로 내가 대답에 또 다른 질문을 설명 .
주석을 사용하여 다음과 같이 할 수 있습니다.
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()
{
}
}
여기, 우리
- JUnit 4.5로 업그레이드,
- 작업 서비스가 필요한 각 테스트 클래스 또는 메서드에 태그를 지정하는 주석을 작성했습니다.
- 서비스의 설정 및 해체를 구현하는 정적 메서드가 포함 된 각 주석에 대한 핸들러를 작성했습니다.
- 테스트에서 주석을 찾기 위해 일반적인 Runner를 확장하여 적절한 지점의 테스트 실행 체인에 정적 핸들러 메서드를 추가했습니다.
"참고 : 우리는 빌드에 maven 2를 사용하고 있습니다. maven의 사전 및 사후 통합 테스트 단계를 사용해 보았지만 테스트가 실패하면 maven이 중지되고 통합 후 테스트를 실행하지 않습니다. , 도움이되지 않습니다. "
대신 failsafe-plugin을 사용해 볼 수 있습니다. 설정이나 중간 단계 상태에 관계없이 정리가 이루어 지도록 보장하는 기능이 있다고 생각합니다.
모든 테스트가 "기술"클래스를 확장하고 동일한 패키지에있는 경우 약간의 트릭을 수행 할 수 있습니다.
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() {}
}
이 솔루션에는 많은 단점이 있습니다.
- 패키지의 모든 테스트를 실행해야합니다.
- "기술"클래스를 하위 클래스로 분류해야합니다.
- @BeforeClass 및 @AfterClass를 하위 클래스 내에서 사용할 수 없습니다.
- 패키지에서 하나의 테스트 만 실행하면 청소가되지 않습니다.
- ...
For information: listClassesIn() => How do you find all subclasses of a given class in Java?
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.
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.
<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>
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
If you don't want to create a suite and have to list all your test classes you can use reflection to find the number of test classes dynamically and count down in a base class @AfterClass to do the tearDown only once:
public class BaseTestClass
{
private static int testClassToRun = 0;
// Counting the classes to run so that we can do the tear down only once
static {
try {
Field field = ClassLoader.class.getDeclaredField("classes");
field.setAccessible(true);
@SuppressWarnings({ "unchecked", "rawtypes" })
Vector<Class> classes = (Vector<Class>) field.get(BlockJUnit4ClassRunner.class.getClassLoader());
for (Class<?> clazz : classes) {
if (clazz.getName().endsWith("Test")) {
testClassToRun++;
}
}
} catch (Exception ignore) {
}
}
// Setup that needs to be done only once
static {
// one time set up
}
@AfterClass
public static void baseTearDown() throws Exception
{
if (--testClassToRun == 0) {
// one time clean up
}
}
}
If you prefer to use @BeforeClass instead of the static blocks, you can also use a boolean flag to do the reflection count and test setup only once at the first call. Hope this helps someone, it took me an afternoon to figure out a better way than enumerating all classes in a suite.
Now all you need to do is extend this class for all your test classes. We already had a base class to provide some common stuff for all our tests so this was the best solution for us.
Inspiration comes from this SO answer https://stackoverflow.com/a/37488620/5930242
If you don't want to extend this class everywhere, this last SO answer might do what you want.
참고URL : https://stackoverflow.com/questions/82949/before-and-after-suite-execution-hook-in-junit-4-x
'Programing' 카테고리의 다른 글
| JavaScript를 사용하여 모든 텍스트를 선택 해제하는 기능이 있습니까? (0) | 2020.10.05 |
|---|---|
| 업로드하기 전에 HTML5를 사용하여 이미지 크기 조정 (0) | 2020.10.05 |
| 컴파일 타임에 응용 프로그램 폴더로 파일 복사 (0) | 2020.10.05 |
| LaTeX에서 두 그림을 같은 페이지에 유지하는 방법은 무엇입니까? (0) | 2020.10.05 |
| kayak.com과 같은 사이트는 어떻게 콘텐츠를 집계합니까? (0) | 2020.10.05 |