JUnit混淆:使用'扩展TestCase'或'@Test'?

我发现JUnit的正确使用(或至less文档)非常混乱。 这个问题既可以作为未来的参考,也可以作为一个真正的问题。

如果我理解正确,创build和运行JUnittesting主要有两种方法:

方法A(JUnit 3样式):创build一个扩展TestCase的类,并用test这个词开始testing方法。 在JUnit Test(在Eclipse中)运行类时,所有以word 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样式):创build一个“普通”类,并在该方法前加上一个@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问题 :

现在,我的问题:

  1. 什么是首选方法 ,或者什么时候使用一个而不是另一个?
  2. 方法B允许通过像@Test(expected = ArithmeticException.class)那样扩展@Test注解来testingexception。 但是,如何使用方法Atestingexception?
  3. 当使用方法A时,您可以在testing套件中对许多testing类进行分组,如下所示:

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

    但这不能用于方法B(因为每个testing类都应该inheritanceTestCase的子类)。 方法B的组合testing的正确方法是什么?

编辑:我已经添加了两种方法的JUnit版本

区别很简单:

  • 扩展TestCase是unit testing用JUnit 3编写的方式(当然它仍然支持JUnit 4)
  • 使用@Test注释是JUnit 4引入的方法

通常,您应该select注释path,除非需要与JUnit 3(和/或早于Java 5的Java版本)的兼容性。 新方法有几个优点:

  • @Test annotaton更加明确,并且更易于在工具中支持(例如,以这种方式search所有testing很容易)
  • 多个方法可以用@Before / @BeforeClass@After / @AfterClass注释,提供更多的灵活性
  • 支持@Rule注释
  • 支持@Ignored注释
  • 支持使用@RunWith替代testing跑步者

为了在JUnit 3 TestCasetesting预期的exception,你必须使文本显式化。

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

我对JUnit 4(Annotation方法)有偏好,因为我觉得它更加灵活。

如果您想在JUnit 4中构buildtesting套件,则必须创build一个类,将所有testing分组,如下所示:

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

你的问题有一个没有答案的部分,那就是“对方法B进行分组testing的正确方法是什么?

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

但是,它有一个倒退,因为注释不允许您dynamic创build类的列表,解决这个问题变得有点难看。 您必须inheritanceSuite类,并在子类中dynamic创build类的数组并将其传递给Suite构造函数,但这是一个不完整的解决scheme,因为Suite的其他子类(例如Categories)不能使用它,不支持dynamictesting类集合。

你应该使用JUnit 4.更好。

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

这是来自Spring 3.0参考文档:

[警告]旧版JUnit 3.8类层次结构已被弃用

一般来说,当你开始新的东西的时候,你总是应该尝试使用最新的稳定的框架版本。

  1. “首选”方法是使用从Junit 4开始引入的注释。它们使许多事情变得更加简单(请参阅第二个问题)

  2. 你可以使用一个简单的try / catch块:

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