1. 概要

この記事では、 LambdaBehaveと呼ばれる新しいJavaベースのテストフレームワークについて説明します。

名前が示すように、このテストフレームワークはJava8Lambdaで動作するように設計されています。 さらに、この記事では、仕様を調べて、それぞれの例を示します。

含める必要のあるMavenの依存関係は次のとおりです。

<dependency>           
    <groupId>com.insightfullogic</groupId>
    <artifactId>lambda-behave</artifactId>
    <version>0.4</version>
</dependency>

最新バージョンはここにあります。

2. 基本

フレームワークの目標の1つは、優れた読みやすさを実現することです。 構文は、ほんの数語ではなく完全な文を使用してテストケースを説明することを推奨します。

パラメータ化されたテストを活用でき、テストケースを事前定義された値にバインドしたくない場合は、ランダムなパラメータを生成できます。

3. Lambdaの動作テストの実装

すべての仕様スイートはSuite.describe。で始まります。この時点で、仕様を宣言するためのいくつかの組み込みメソッドがあります。 したがって、 Suite はJUnitテストクラスのようなものであり、仕様はJUnitの@Testで注釈が付けられたメソッドのようなものです。

テストを説明するために、 したほうがいい()。 同様に、期待値ラムダパラメーターに次のように名前を付けると “予想”、 テストからどのような結果が期待できるかを、次のように言うことができます。 expected.that()

仕様の前後のデータをセットアップまたは破棄する場合は、次を使用できます。 it.isSetupWith() と it.isConcludedWith()。 同様に、前後に何かをするためにスイート 、使用します it.initiatizesWith() it.completesWith()。

Calculatorクラスの簡単なテスト仕様の例を見てみましょう。

public class Calculator {

    public int add() {
        return this.x + this.y;
    }

    public int divide(int a, int b) {
        if (b == 0) {
            throw new ArithmeticException();
        }
        return a / b;
    }
}

から始めましょう Suite.describe 次に、コードを追加して初期化します電卓。

次に、仕様を記述して add()メソッドをテストします。

{
    Suite.describe("Lambda behave example tests", it -> {
        it.isSetupWith(() -> {
            calculator = new Calculator(1, 2);
        });
 
        it.should("Add the given numbers", expect -> {
            expect.that(calculator.add()).is(3);
        });
}

ここでは、読みやすくするために、変数に「it」および「expect」という名前を付けました。 これらはラムダパラメーター名であるため、任意の名前に置き換えることができます。

should()の最初の引数は、このテストで何をチェックすべきか、平易な英語を使用することを説明しています。 2番目の引数はラムダです。これは、 add()メソッドが3を返す必要があることを示しています。

ゼロ除算のテストケースをもう1つ追加して、例外が発生するかどうかを確認しましょう。

it.should("Throw an exception if divide by 0", expect -> {
    expect.exception(ArithmeticException.class, () -> {
        calculator.divide(1, 0);
    });
});

この場合、例外が発生することが予想されるため、 expected.exception()と記述し、その中に例外をスローするコードを記述します。

テキストの説明は、仕様ごとに一意である必要があることに注意してください。

4. データ駆動型の仕様

このフレームワークにより、仕様レベルでのテストパラメータ化が可能になります。

例を作成するために、Calculatorクラスにメソッドを追加しましょう。

public int add(int a, int b) {
    return a + b;
}

そのためのデータ駆動型テストを書いてみましょう。

it.uses(2, 3, 5)
  .and(23, 10, 33)
  .toShow("%d + %d = %d", (expect, a, b, c) -> {
    expect.that(calculator.add(a, b)).is(c);
});

used()メソッドは、さまざまな列数で入力データを指定するために使用されます。 最初の2つの引数はadd()関数パラメーターであり、3番目の引数は期待される結果です。 これらのパラメーターは、テストに示されているように、説明でも使用できます。

toShow()は、パラメーターを使用してテストを記述するために使用されます–次の出力を使用します。

0: 2 + 3 = 5 (seed: 42562700892554)(Lambda behave example tests)
1: 23 + 10 = 33 (seed: 42562700892554)(Lambda behave example tests)

5. 生成された仕様–プロパティベースのテスト

通常、単体テストを作成するときは、システムに当てはまるより広範なプロパティに焦点を当てたいと思います。

たとえば、私たちがテストするとき反転機能、特定の反転を行うとチェックする場合があります 2回、オリジナルになります弦。

プロパティベースのテストは、特定のテストパラメータをハードコーディングせずに一般的なプロパティに焦点を当てています。ランダムに生成されたテストケースを使用することでこれを実現できます。

この戦略は、データ駆動型の仕様を使用する場合と似ていますが、データのテーブルを指定する代わりに、生成するテストケースの数を指定します。

したがって、String反転プロパティベースのテストは次のようになります。

it.requires(2)
  .example(Generator.asciiStrings())
  .toShow("Reversing a String twice returns the original String", 
    (expect, str) -> {
        String same = new StringBuilder(str)
          .reverse().reverse().toString();
        expect.that(same).isEqualTo(str);
   });

は、 require()メソッドを使用して必要なテストケースの数を示しています。 example()句を使用して、必要なオブジェクトのタイプと方法を示します。

この仕様の出力は次のとおりです。

0: Reversing a String twice returns the original String(ljL+qz2) 
  (seed: 42562700892554)(Lambda behave example tests)
1: Reversing a String twice returns the original String(g) 
  (seed: 42562700892554)(Lambda behave example tests)

5.1. 決定論的テストケースの生成

自動生成されたテストケースを使用すると、テストの失敗を特定することが非常に困難になります。 たとえば、機能が1000回に1回失敗した場合、エラーを監視するには、10ケースのみを自動生成する仕様を何度も実行する必要があります。

したがって、以前に失敗したケースを含め、テストを決定論的に再実行する機能が必要です。

LambdaBehaveはこの問題に対処できます。 前のテストケースの出力に示されているように、ランダムなテストケースのセットを生成するために使用されたシードを出力します。 したがって、何かが失敗した場合、シードを使用して以前に生成されたテストケースを再作成できます。

テストケースの出力を見て、シードを特定できます:(シード:42562700892554)。 これで、同じテストセットを再度生成するために、SourceGeneratorを使用できます。

SourceGenerator には、引数としてシードのみを受け取る deterministicNumbers()メソッドが含まれています。

 it.requires(2)
   .withSource(SourceGenerator.deterministicNumbers(42562700892554L))
   .example(Generator.asciiStrings())
   .toShow("Reversing a String twice returns the original String", 
     (expect, str) -> {
       String same = new StringBuilder(str).reverse()
         .reverse()
         .toString();
       expect.that(same).isEqualTo(str);
});

このテストを実行すると、前に見たのと同じ出力が得られます。

6. 結論

この記事では、Lambda Behaveと呼ばれる新しい流暢なテストフレームワークで、Java8ラムダ式を使用して単体テストを作成する方法を説明しました。

いつものように、これらの例のコードはGitHubにあります。