JUnit混淆:使用'extends TestCase'还是'@Test'?

时间:2010-04-14 08:16:28

标签: java junit automated-tests

我发现JUnit的正确使用(或至少是文档)非常令人困惑。 这个问题既是未来的参考,也是一个真实的问题。

如果我理解正确,创建和运行JUnit测试有两种主要方法:

方法A(JUnit 3样式):创建一个扩展TestCase的类,并使用单词test启动测试方法。当将类作为JUnit Test运行时(在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);
    }
}

混合两者似乎不是一个好主意,请参阅例如this stackoverflow question

现在,我的问题:

  1. 首选方法,或何时使用其中一种而非另一种?
  2. 方法B允许通过扩展@ @Test(expected = ArithmeticException.class)中的@Test注释来测试异常。 但是,如何在使用方法A时测试异常?
  3. 使用方法A时,您可以在测试套件中对许多测试类进行分组,如下所示:

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

    但是这不能用于方法B(因为每个测试类应该是TestCase的子类)。 对方法B进行分组测试的正确方法是什么?

  4. 编辑:我已将JUnit版本添加到两种方法

5 个答案:

答案 0 :(得分:108)

区别很简单:

  • 扩展TestCase是单元测试在JUnit 3中编写的方式(当然它在JUnit 4中仍然受支持)
  • 使用@Test注释是JUnit 4
  • 引入的方式

通常,您应该选择注释路径,除非需要与JUnit 3(和/或Java 5之前的Java版本)兼容。新方法有几个优点:

要测试JUnit 3 TestCase中的预期异常,您必须明确显示文本。

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
  }
}

答案 1 :(得分:24)

我更喜欢JUnit 4(注释方法),因为我觉得它更灵活。

如果你想在JUnit 4中构建测试套件,你必须创建一个类,对所有测试进行分组:

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 */
}

答案 2 :(得分:15)

您的问题有一个未解答的部分,那就是“对方法B进行分组测试的正确方法是什么?”

官方答案是您使用@RunWith(Suite.class)注释类,然后使用@ Suite.SuiteClasses批注列出类。这就是JUnit开发人员如何做到这一点(手动列出套件中的每个类)。在许多方面,这种方法是一种改进,因为在套件和套件后行为之前添加它是微不足道和直观的(只需将@BeforeClass和@AfterClass方法添加到使用@RunWith注释的类中 - 比旧的TestFixture更好)。

然而,它确实有一个倒退,因为注释不允许您动态创建类列表,并解决该问题有点难看。您必须继承Suite类并在子类中动态创建类数组并将其传递给Suite构造函数,但这是一个不完整的解决方案,因为Suite的其他子类(如Categories)不能与它一起使用不支持动态Test类集合。

答案 3 :(得分:4)

你应该使用JUnit 4.它更好。

许多框架已经开始弃用JUnit 3.8支持。

这是来自Spring 3.0参考文档:

  

[警告] Legacy JUnit 3.8类   不推荐使用层次结构

通常,在开始新事物时,应始终尝试使用框架的最新稳定版本。

答案 4 :(得分:1)

  1. “首选”方法是使用自Junit 4以来引入的注释。它们使事情变得更容易(参见第二个问题)

  2. 您可以使用简单的try / catch块:

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