Programing

JUnit 혼란 : 'Extends TestCase'또는 '@Test'?

lottogame 2020. 6. 15. 08:18
반응형

JUnit 혼란 : 'Extends TestCase'또는 '@Test'?


JUnit의 올바른 사용 (또는 적어도 문서)이 매우 혼란 스럽다는 것을 알았습니다. 이 질문은 향후 참조 및 실제 질문으로 사용됩니다.

내가 올바르게 이해했다면 JUnit 테스트를 만들고 실행하는 두 가지 주요 접근법이 있습니다.

접근법 A (JUnit 3 스타일) : TestCase를 확장하는 클래스를 작성하고 단어로 테스트 메소드를 시작하십시오 test. 클래스를 JUnit 테스트 (Eclipse에서)로 test실행 하면 단어 시작하는 모든 메소드 가 자동으로 실행됩니다.

import junit.framework.TestCase;

public class DummyTestA extends TestCase {

    public void testSum() {
        int a = 5;
        int b = 10;
        int result = a + b;
        assertEquals(15, result);
    }
}

접근법 B (JUnit 4 스타일) : '일반'클래스 @Test를 작성하고 메소드 앞에 주석을 추가하십시오 . 단어로 메소드를 시작할 필요는 없습니다 test.

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

public class DummyTestB {

    @Test
    public void Sum() {
        int a = 5;
        int b = 10;
        int result = a + b;
        assertEquals(15, result);
    }
}

두 가지를 혼합하는 것은 좋은 생각이 아닌 것 같습니다. 예를 들어이 stackoverflow question을 참조하십시오 .

이제 내 질문 :

  1. 선호하는 방법은 무엇입니까 , 아니면 언제 다른 방법을 사용합니까?
  2. 접근법 B는에서와 같이 @Test 주석을 확장하여 예외 테스트를 허용합니다 @Test(expected = ArithmeticException.class). 그러나 접근법 A를 사용할 때 예외를 어떻게 테스트합니까?
  3. 접근법 A를 사용할 때 다음과 같이 테스트 스위트에서 여러 테스트 클래스를 그룹화 할 수 있습니다.

    TestSuite suite = new TestSuite("All tests");
    suite.addTestSuite(DummyTestA.class);
    suite.addTestSuite(DummyTestAbis.class);

    그러나 이것은 각 테스트 클래스가 TestCase를 서브 클래스 화해야하기 때문에 접근법 B와 함께 사용할 수 없습니다. 접근법 B에 대한 테스트를 그룹화하는 올바른 방법은 무엇입니까?

편집 : JUnit 버전을 두 가지 접근법 모두에 추가했습니다.


구별은 다소 쉽습니다.

  • 확장 TestCase은 단위 테스트가 JUnit 3에서 작성된 방식입니다 (물론 JUnit 4에서도 여전히 지원됩니다)
  • @Test주석을 사용하는 것은 JUnit 4에 의해 도입 된 방법입니다

JUnit 3 (또는 Java 5 이전의 Java 버전)과의 호환성이 필요하지 않은 경우 일반적으로 주석 경로를 선택해야합니다. 새로운 방법에는 몇 가지 장점이 있습니다.

To test for expected exceptions in a JUnit 3 TestCase you'd have to make the text explicit.

public void testMyException() {
  try {
    objectUnderTest.myMethod(EVIL_ARGUMENT);
    fail("myMethod did not throw an Exception!");
  } catch (MyException e) {
    // ok!
    // check for properties of exception here, if desired
  }
}

I have a preference for JUnit 4 (Annotation approach) because I find it more flexible.

If you want to build test suite in JUnit 4, you have to create a class grouping all tests like this:

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


@RunWith(Suite.class)
@SuiteClasses({
    Test1.class,
    Test2.class,
    Test3.class,
    Test4.class
})public class TestSuite
{
 /* empty class */
}

There is an unanswered part to your question, and that is "What is the proper way to group tests for approach B?"

The official answer is that you annotate a class with an @RunWith(Suite.class) and then use the @Suite.SuiteClasses annotation to list the classes. This is how the JUnit developers do it (listing every class in a suite manually). In many ways this approach is an improvement, in that it is trivial and intuitive to add before suite and after suite behaviors (just add an @BeforeClass and @AfterClass method to the the class annotated with the @RunWith - much better than the old TestFixture).

However, it does have a step backwards, in that annotations don't allow you to dynamically create the list of classes, and working around that problem gets a bit ugly. You have to subclass the Suite class and dynamically create the array of classes in the subclass and pass it to the Suite constructor, but this is an incomplete solution in that other subclasses of Suite (such as Categories) don't work with it and essentially do not support dynamic Test class collection.


You should use JUnit 4. It's better.

Much frameworks have started to deprecate the JUnit 3.8 support.

This is from the Spring 3.0 reference documentation:

[Warning] Legacy JUnit 3.8 class hierarchy is deprecated

In general, you should always try to use the latest stable release of a framework when you start something new.


  1. The "preferred" approach would be to use annotations which have been introduced since Junit 4. They make a lot of things easier (see your second question)

  2. You can use a simple try/catch block for that:


public void testForException() {
    try {
        Integer.parseInt("just a string");
        fail("Exception should have been thrown");
    } catch (final Exception e) {
        // expected
    }
}

참고URL : https://stackoverflow.com/questions/2635839/junit-confusion-use-extends-testcase-or-test

반응형