【问题标题】:JUnit confusion: use 'extends TestCase' or '@Test'?JUnit 混淆:使用“扩展 TestCase”或“@Test”?
【发布时间】:2010-04-14 08:16:27
【问题描述】:

我发现 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);
    }
}

将两者混合似乎不是一个好主意,请参见例如this 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);

    但这不能与方法 B 一起使用(因为每个测试类都应该是 TestCase 的子类)。 为方法 B 分组测试的正确方法是什么?

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

【问题讨论】:

  • 我见过extends TestCase,然后每个测试也用@Test 注释只是为了混淆。 :)

标签: java junit automated-tests


【解决方案1】:

区别很简单:

  • 扩展 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
  }
}

JUnit 5 引入了另一个 API 更改,但仍使用注释。新的 @Test 注释是 org.junit.jupiter.api.Test(“旧”JUnit 4 注释是 org.junit.Test),但它的工作方式与 JUnit 4 注释几乎相同。

【讨论】:

  • 有用而彻底的答案,但我不完全理解“检查异常消息”。检查硬编码字符串将成为维护的噩梦。您的意思一定是“检查特定异常类型的属性”。
  • @thSoft:它不经常使用,但偶尔我想确保异常方法提到了违规字段。那么一个简单的assertTrue(e.getMessage().contains("foo")) 可能会很有用。
  • 即使在 JUnit4 中,当您必须检查异常的消息或其他一些属性(例如原因)时,这也是一个重要的习惯用法。 expected 方法只检查类型。
  • @Yishai:没错,但大多数时候,如果该方法在有问题的输入上抛出正确类型的异常,我已经很满足了。
  • 出于这个原因,JUnit 5 在异常测试方面做出了重大改变。 assertThrows() 太棒了:-)
【解决方案2】:

我更喜欢 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 */
}

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 为此 +1。在着手编写将测试添加到 TestSuite 的动态解决方案之后,我不得不在我的每个测试中扩展 TestCase。这反过来又破坏了以前使用 JUnit4 注释来定义预期异常的工作单元测试。我对动态填充测试套件的方法的搜索使我找到了这个线程,特别是您的答案,我认为这是继续使用 JUnit 3 的少数几个理想的理由之一。
    【解决方案4】:

    您应该使用 JUnit 4。它更好。

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

    这是来自 Spring 3.0 参考文档:

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

    一般来说,当您开始新事物时,您应该始终尝试使用框架的最新稳定版本。

    【讨论】:

      【解决方案5】:
      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
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-28
        • 1970-01-01
        • 1970-01-01
        • 2014-10-20
        • 2010-09-17
        相关资源
        最近更新 更多