1. 概要

JGoTesting は、Goのテストパッケージに触発されたJUnit互換のテストフレームワークです。

この記事では、JGoTestingフレームワークの主要な機能を調べ、その機能を紹介する例を実装します。

2. Mavenの依存関係

まず、jgotesting依存関係をpom.xmlに追加しましょう。

<dependency>
    <groupId>org.jgotesting</groupId>
    <artifactId>jgotesting</artifactId>
    <version>0.12</version>
</dependency>

このアーティファクトの最新バージョンはここにあります。

3. 序章

JGoTestingを使用すると、JUnitと互換性のあるテストを作成できます。 JGoTestingが提供するすべてのアサーションメソッドに対して、同じシグネチャを持つJUnitに1つあります。したがって、このライブラリの実装は非常に簡単です。

ただし、 JUnitとは異なり、アサーションが失敗しても、JGoTestingはテストの実行を停止しません。 代わりに、失敗はイベントとして記録され、すべてのアサーションが実行されたときにのみ表示されます。

4. JGoTestingの動作

このセクションでは、JGoTestingをセットアップし、その可能性を探る方法の例を示します。

4.1. 入門

テストを作成するために、最初にJGoTestingのアサーションメソッドをインポートしましょう。

import static org.jgotesting.Assert.*; // same methods as JUnit
import static org.jgotesting.Check.*; // aliases starting with "check"
import static org.jgotesting.Testing.*;

ライブラリには、@Ruleアノテーションでマークされた必須のJGoTestRuleインスタンスが必要です。 これは、クラス内のすべてのテストがJGoTestingによって管理されることを示しています。

そのようなルールを宣言するクラスを作成しましょう:

public class JGoTestingUnitTest {
 
    @Rule
    public final JGoTestRule test = new JGoTestRule();
    
    //...
}

4.2. ライティングテスト

JGoTestingは、テストを作成するための2セットのアサーションメソッドを提供します。 最初のセットのメソッドの名前はassertで始まり、JUnitと互換性のあるものであり、他のメソッドはcheckで始まります。

メソッドの両方のセットは同じように動作し、ライブラリはそれらの間で1対1の対応を提供します。

両方のバージョンを使用して、数値が別の数値と等しいかどうかをテストする例を次に示します。

@Test
public void whenComparingIntegers_thenEqual() {
    int anInt = 10;

    assertEquals(anInt, 10);
    checkEquals(anInt, 10);
}

APIの残りの部分は自明であるため、これ以上の詳細は説明しません。 以下のすべての例では、checkバージョンのメソッドのみに焦点を当てます。

4.3. 障害イベントとメッセージ

チェックが失敗すると、JGoTestingはテストケースが実行を継続できるように、失敗を記録します。 テストが終了すると、失敗が報告されます

これがどのように見えるかを示す例を次に示します。

@Test
public void whenComparingStrings_thenMultipleFailingAssertions() {
    String aString = "The test string";
    String anotherString = "The test String";

    checkEquals("Strings are not equal!", aString, equalTo(anotherString));
    checkTrue("String is longer than one character", aString.length() == 1);
    checkTrue("A failing message", aString.length() == 2);
}

テストを実行すると、次の出力が得られます。

org.junit.ComparisonFailure: Strings are not equal!
  expected:<[the test s]tring> but was:<[The Test S]tring>
// ...
java.lang.AssertionError: String is longer than one character
// ...
java.lang.AssertionError: Strings are not the same
  expected the same:<the test string> was not:<The Test String>

各メソッドで失敗メッセージを渡すだけでなく、テストに少なくとも1つの失敗があった場合にのみ表示されるように、それらをログに記録することもできます。

これを実践するテストメソッドを書いてみましょう。

@Test
public void whenComparingNumbers_thenLoggedMessage() {
    log("There was something wrong when comparing numbers");

    int anInt = 10;
    int anotherInt = 10;

    checkEquals(anInt, 10);
    checkTrue("First number should be bigger", 10 > anotherInt);
    checkSame(anInt, anotherInt);
}

テストの実行後、次の出力が得られます。

org.jgotesting.events.LogMessage: There was something wrong
  when comparing numbers
// ...
java.lang.AssertionError: First number should be bigger

メッセージをString.format()メソッドとしてフォーマットできる logf()に加えて、 logIf( )および logUnless()メソッドは、条件式に基づいてメッセージをログに記録します。

4.4. テストの中断

JGoTestingは、テストケースが特定の前提条件に合格しなかった場合に、テストケースを終了するいくつかの方法を提供します。

必要なファイルが存在しないためにテストが途中で終了するテストの例を次に示します。

@Test
public void givenFile_whenDoesnotExists_thenTerminated() throws Exception {
    File aFile = new File("a_dummy_file.txt");

    terminateIf(aFile.exists(), is(false));

    // this doesn't get executed
    checkEquals(aFile.getName(), "a_dummy_file.txt");
}

terminate()メソッドと terminateUnless()メソッドを使用して、テストの実行を中断することもできます。

4.5. 連鎖

JGoTestRule クラスには流暢なAPIもあり、これを使用してチェックを連鎖させることができます

JGoTestRule のインスタンスを使用して、Stringオブジェクトの複数のチェックをチェーン化する例を見てみましょう。

@Test
public void whenComparingStrings_thenMultipleAssertions() {
    String aString = "This is a string";
    String anotherString = "This Is a String";

    test.check(aString, equalToIgnoringCase(anotherString))
      .check(aString.length() == 16)
      .check(aString.startsWith("This"));
}

4.6. カスタムチェック

boolean式とMatcherインスタンスに加えて、JGoTestRuleのメソッドはカスタムCheckerオブジェクトを受け入れてチェックを実行できます。 これは、ラムダ式を使用して実装できるシングル抽象メソッドインターフェイスです。

次に、前述のインターフェイスを使用して、Stringが特定の正規表現と一致するかどうかを確認する例を示します。

@Test
public void givenChecker_whenComparingStrings_thenEqual() throws Exception {
    Checker<String> aChecker = s -> s.matches("\\d+");

    String aString = "1235";

    test.check(aString, aChecker);
}

5. 結論

このクイックチュートリアルでは、JGoTestingがテストを作成するために提供する機能について説明しました。

JUnit互換のassertメソッドと、それに対応するcheckメソッドを紹介しました。 また、ライブラリが失敗イベントを記録および報告する方法も確認し、ラムダ式を使用してカスタムCheckerを作成しました。

いつものように、この記事の完全なソースコードは、Githubにあります。