web-dev-qa-db-ja.com

JUnitの混乱:「extends TestCase」または「@Test」を使用しますか?

JUnitの適切な使用(または少なくともドキュメント)が非常に紛らわしいことがわかりました。この質問は、将来の参照と実際の質問の両方として役立ちます。

正しく理解できた場合、JUnitテストを作成して実行するには、主に2つの方法があります。

アプローチA(JUnit 3スタイル):TestCaseを拡張するクラスを作成し、Word testでテストメソッドを開始します。クラスをJUnitテストとして(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スタイル):「通常」クラスを作成し、メソッドに@Test注釈を付加します。 Word 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);
    }
}

2つを混ぜることは良い考えではないようです。 このstackoverflowの質問

さて、私の質問:

  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のテストをグループ化する適切な方法は何ですか?

編集:私は両方のアプローチにJUnitバージョンを追加しました

146
Rabarberski

区別はかなり簡単です。

  • 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
  }
}
111
Joachim Sauer

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

あなたの質問には未回答の部分があり、それは「アプローチBのテストをグループ化する適切な方法は何ですか?」です。

公式の答えは、@ RunWith(Suite.class)でクラスに注釈を付けてから、@ Suite.SuiteClasses注釈を使用してクラスをリストすることです。これは、JUnit開発者が行う方法です(スイート内のすべてのクラスを手動でリストします)。多くの点で、このアプローチは改善されており、スイートの前とスイートの動作を追加するのは簡単で直感的です(@RunWithアノテーションが付けられたクラスに@BeforeClassおよび@AfterClassメソッドを追加するだけで、古いTestFixtureよりもはるかに優れています) )。

ただし、アノテーションを使用するとクラスのリストを動的に作成することができず、その問題の回避が少し面倒になります。 Suiteクラスをサブクラス化し、サブクラスにクラスの配列を動的に作成してSuiteコンストラクターに渡す必要がありますが、これはSuiteの他のサブクラス(カテゴリなど)が機能せず、本質的には不完全なソリューションです動的テストクラスのコレクションはサポートしていません。

15
Yishai

JUnit 4を使用する必要があります。

多くのフレームワークがJUnit 3.8のサポートを廃止し始めています。

これは、Spring 3.0リファレンスドキュメントからのものです。

[警告]レガシーJUnit 3.8クラス階層は非推奨です

一般に、何か新しいことを始めるときは、常にフレームワークの最新の安定したリリースを使用するようにしてください。

4
Espen
  1. 「好ましい」アプローチは、Junit 4以降に導入された注釈を使用することです。これらは多くのことを簡単にします(2番目の質問を参照)

  2. そのために、単純なtry/catchブロックを使用できます。


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