JUnit4 fail()はここにありますが、pass()はどこにありますか?


85

fail()JUnit4ライブラリにメソッドがあります。私はそれが好きですが、不足を経験していますpass()ですが、ライブラリに存在しないメソッドのしています。なぜそうなのですか?

assertTrue(true)代わりに使用できることがわかりましたが、それでも論理的ではありません。

@Test
 public void testSetterForeignWord(){
  try {
   card.setForeignWord("");
   fail();
  } catch (IncorrectArgumentForSetter ex){
  }

 // assertTrue(true);
 }

7
returnステートメントを使用するだけです-ほとんどの場合、pass()として渡されます。
topchef 2010年

@topchefその単一のコメントは頭に打撃を与えましたが、他の誰もがどちらが受け入れられ、どれが受け入れられないかについて議論しています。

一部のテストシステム(perl Test :: Simple)は、成功したアサーションと失敗したアサーションをカウントします。ただし、JUnitは、合格および不合格のテストメソッドの数をカウントします。したがって、Junitはpassメソッドを同じように使用することはありません。
Randall Whitman

回答:


65

テストが例外をスローしない限り、@Testアノテーションで予期される例外が指定されていない限り、テストは合格です。pass()テストを短絡させるために、JUnitが常に合格と解釈する特別な例外をスローする可能性があると思いますが、それは通常のテストの設計に反します(つまり、成功を想定し、アサーションが失敗した場合にのみ失敗します)。使用することが望ましいという考えは、pass()(例外作成のオーバーヘッドのために)合格するテストの大規模なスイートを大幅に遅くします。テストに失敗することは当たり前のことではないので、そのオーバーヘッドがあれば大したことではありません。

あなたの例は次のように書き直すことができることに注意してください:

@Test(expected=IncorrectArgumentForSetter.class)
public void testSetterForeignWord("") throws Exception {
  card.setForeignWord("");
}

また、標準のJava例外の使用を優先する必要があります。あなたIncorrectArgumentForSetterはおそらくIllegalArgumentExceptionです。


4
fail()メソッドとassertX()メソッドは、実際にはAssertionErrorをスローするだけであり、これによりテストメソッドが不正に終了します。だからこそ、成功したリターンは成功を意味します...
Steven Schlansker 2010年

-1-pass()メソッドは何もしていません-例外なくすぐにテストを終了しています。これは、ほとんどの場合(予期される例外、タイムアウトなどを除く)、returnステートメントと実質的に同等です。
topchef 2010年

1
@grigory:pass()メソッドを呼び出した後にテストが失敗する可能性がないように、メソッドは何もできないというのは正しいです。だから私はその文を削除しました。
ColinD 2010年

私はあなたに十分に感謝することができません、私がたくさんの欲求不満から抜け出すのを手伝ってくれました!
n00b Pr0grammer 2018年

71

returnテストが終了して合格したときはいつでもステートメントを呼び出します。


3
+1は正解である必要があります(予想されるタイムアウトなどを除いて、ほとんどの場合)
トップシェフ2010年

確かに、テストを終了するための最も簡単で使いやすい方法のようです。
ベンジ2018年

7

ここでの回答のほとんどはかなり時代遅れなので、この質問には更新された回答が必要だと思います。

まず、OPの質問に:

「期待される例外」の概念をJUnitに導入することは、その例外がどこでも発生する可能性があり、テストに合格するため、悪い動きであったことはかなり受け入れられていると思います。非常にドメイン固有の例外をスロー(およびアサート)する場合は機能しますが、完全に完全である必要があるコードで作業している場合にのみ、これらの種類の例外をスローします-ほとんどのAPISは、IllegalArgumentExceptionまたはのような組み込みの例外を単にスローしますIllegalStateException。2回の呼び出しでこれらの例外が発生する可能性がある場合は、@ExpectedException場合、例外をスローする行が間違っていてもアノテーションによってテストが緑色で表示されます。

この状況のた​​めに、私はここにいる他の多くの人が書いたと確信しているクラスを書きました。それはassertThrowsメソッドです。

public class Exceptions {
    private Exceptions(){}

    public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){
        try{
            actionThatShouldThrow.run();
            fail("expected action to throw " + expectedException.getSimpleName() + " but it did not.");
        }
        catch(Exception e){
            if ( ! expectedException.isInstance(e)) {
                throw e;
            }
        }
    }
}

このメソッドは、例外がスローされた場合に単に返されるため、テストでさらにアサーション/検証を行うことができます。

Java 8構文を使用すると、テストは非常に見栄えがします。以下は、このメソッドを使用するモデルでのより簡単なテストの1つです。

@Test
public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() {
    //setup
    AxisRange range = new AxisRange(0,100);

    //act
    Runnable act = () -> range.setLowerBound(200);

    //assert
    assertThrows(IllegalArgumentException.class, act);
}

「act」ステップは実際にはアクションを実行しないため、これらのテストは少し不安定ですが、意味はまだかなり明確だと思います。

mavenにはcatch-exceptionと呼ばれる小さなライブラリもあり、mockitoスタイルの構文を使用して例外がスローされることを確認します。見た目はきれいですが、私は動的プロキシのファンではありません。とは言うものの、構文が非常に洗練されているため、魅力的なままです。

// given: an empty list
List myList = new ArrayList();

// when: we try to get the first element of the list
// then: catch the exception if any is thrown 
catchException(myList).get(1);

// then: we expect an IndexOutOfBoundsException
assert caughtException() instanceof IndexOutOfBoundsException;

最後に、私がこのスレッドにたどり着くために遭遇した状況については、無視する方法があります何らかの条件が満たされた場合にテストます。

現在、JNAと呼ばれるjava native-library-loading-libraryを介して呼び出されるDLLの取得に取り組んでいますが、ビルドサーバーはubuntuにあります。私は、JUnitテストを使用してこの種の開発を推進しようとしていますが、現時点では「ユニット」からはほど遠いです。私がやりたいのは、ローカルマシンを使用している場合はテストを実行することですが、ubuntuを使用している場合はテストを無視します。JUnit 4には、次のような機能がありAssumeます。

@Test
public void when_asking_JNA_to_load_a_dll() throws URISyntaxException {
    //this line will cause the test to be branded as "ignored" when "isCircleCI" 
    //(the machine running ubuntu is running this test) is true.
    Assume.assumeFalse(BootstrappingUtilities.isCircleCI());
    //an ignored test will typically result in some qualifier being put on the results, 
    //but will also not typically prevent a green-ton most platforms. 

    //setup
    URL url = DLLTestFixture.class.getResource("USERDLL.dll");
    String path = url.toURI().getPath();
    path = path.substring(0, path.lastIndexOf("/"));

    //act
    NativeLibrary.addSearchPath("USERDLL", path);
    Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class);

    //assert
    assertThat(dll).isNotNull();
}

あなたが言ったように、「act」は特定のことを何もしないので、それが私たちが期待している行であるかどうかにかかわらず、例外を正確にスローするものはまだわかりません。この場合、例はテストと検証が非常に簡単ですが、結果を返す前にネストされたメソッドを使用するUtilityメソッドがテストに含まれていると想像してください。IDEが例外サイトを示さない限り、問題の原因を
Farid

4

pass一部のシナリオでは適用できないいくつかのテストを短絡できるように、JUnitのメソッドも探していました(純粋な単体テストではなく統合テストがあります)。残念ながらそこにはありません。

幸い、条件付きでテストを無視する方法があります。これは、私の場合、次のassumeTrue方法を使用するとさらに適切になります。

Assume.assumeTrue(isTestApplicable);

したがって、ここでは、isTestApplicableがtrueの場合にのみテストが実行され、それ以外の場合はテストが無視されます。


2

テストコードからAssertionFailedExceptionがスローされない場合、単体テストケースが合格するため、passメソッドは必要ありません。

fail()メソッドは、実際にはAssertionFailedExceptionをスローして、制御がそのポイントに到達した場合にtestCaseを失敗させます。


実際にはjunit.framework.AssertionFailedErrorだと思います。
カイル2011年

エラーの場合はどうですか。iamがwebdriverから要素が表示されない例外を取得していると言います。例外をキャッチして返す必要があります。
sasikumar 2012

1

この質問は、テスト実行プロセスの少しの誤解の結果だと思います。JUnit(およびその他のテストツール)では、結果はアサート呼び出しごとではなく、メソッドごとにカウントされます。assertX実行された合格/不合格の数を追跡するカウンターはありません。

JUnitは、各テストメソッドを個別に実行します。メソッドが正常に戻った場合、テストは「合格」として登録されています。例外が発生した場合、テストは「失敗」として登録されます。後者の場合、2つのサブケースが考えられます:1)JUnitアサーション例外、2)その他の種類の例外。ステータスは、最初のケースでは「失敗」、2番目のケースでは「エラー」になります。

このAssertクラスでは、アサーション例外をスローするために多くの省略形メソッドを使用できます。言い換えれば、AssertはJUnitの例外に対する抽象化レイヤーです。

例えば、これは、ソースコードassertEqualsGitHubの

/**
 * Asserts that two Strings are equal.
 */
static public void assertEquals(String message, String expected, String actual) {
    if (expected == null && actual == null) {
        return;
    }
    if (expected != null && expected.equals(actual)) {
        return;
    }
    String cleanMessage = message == null ? "" : message;
    throw new ComparisonFailure(cleanMessage, expected, actual);
}

ご覧のとおり、平等の場合は何も起こりません。そうでない場合は例外がスローされます。

そう:

assertEqual("Oh!", "Some string", "Another string!");

ComparisonFailureJUnitによってキャッチされる例外をスローするだけで、

assertEqual("Oh?", "Same string", "Same string");

何もしません。

要するに、pass()それは何もしなかったので、のようなものは意味がありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.