英語版
このページの英語版を見る

単体テスト

UnitTest:
    unittest BlockStatement

ユニットテストとは、モジュールが正しく動作しているかどうかを判定するために をモジュールに適用して、そのモジュールが正しく動作しているかどうかを判定する。 Dプログラムは、ユニットテストを有効または無効にして実行することができる。

ユニットテストは、次のように定義された特別な関数である:

unittest
{
    ...test code...
}

ユニット・テストでは、AssertExpressionsを使って個々のテストを指定する。 他の場所で使われるAssertExpressionsとは異なり、アサートは保持されることを仮定しない。 が失敗しても、プログラムはまだ定義された状態にある。

モジュール内には、いくつでもユニットテスト関数を書くことができる、 構造体、共用体、クラス宣言の中も含む。 これらは()()順に実行される。

ユニットテストを有効にすると、すべての静的初期化が完了した後、 関数が呼び出される前に実行される。 完了後、main() 関数が呼ばれる前に実行される。

例えば、2つの値を加算するSum 。 テストを与えることができる:

class Sum
{
    int add(int x, int y) { return x + y; }

    unittest
    {
        Sum sum = new Sum;
        assert(sum.add(3,4) == 7);
        assert(sum.add(-2,0) == -2);
    }
}

ユニットテストが有効な場合、バージョン識別子 unittest はあらかじめ定義されている。

属性付きユニテスト

ユニテストは、グローバル関数属性のいずれかに帰属させることができる。 このようなユニテストは、テンプレート上で指定された属性を検証するのに便利である。 関数を検証するのに便利である:

void myFunc(T)(T[] data)
{
    if (data.length > 2)
        data[0] = data[1];
}

@safe nothrow unittest
{
    auto arr = [1,2,3];
    myFunc(arr);
    assert(arr == [2,2,3]);
}

このユニテストは、myFunc@safe のみを含むことを検証する、 nothrow コードのみを含むことを検証する。このユニテストは、 が のコードしか含まないことを検証する。 myFunc myFuncT 、そのメソッドに@system 、またはコードをスローする opAssign メソッドや、myFunc が呼び出す可能性のある他のメソッドでインスタンス化されるのを防ぐことができる。上記の イディオムによって、myFunc 、そのような型とインスタンス化することができる。 同時に、@system とスローの動作が、 自体のコードによって導入されたものではないことを確認する。 myFunc

実装定義:
  1. ユニットテストが有効でない場合、実装は次のことを行う必要はない。 チェックする必要はない。 これは、より大きなユニットテスト・セクションのコンパイル時の影響を減らすためである。 トークンは依然として有効でなければならない。 {} トークンを数えて、UnitTestの BlockStatementの終わりを見つけるだけである。
  2. ユーザーに対するユニットテスト結果の表示。
  3. ユニットテストを有効または無効にする方法。コンパイラの スイッチの使用。 -unittestなどのコンパイラー・スイッチを使用して などの使用が推奨される。
  4. モジュールがユニットテストを実行するために呼び出される順番。
  5. 最初のユニットテストの失敗でプログラムが停止するか、ユニットテストの実行を継続するか。
ベストプラクティス:
  1. カバレッジ・テストと組み合わせてユニットテストを使う (たとえば -cov) を併用するのが効果的だ。
  2. ある関数の単体テストは、その関数の直後に現れるべきである。 の直後に現れるべきである。

文書化されたユニテスト

ドキュメント化された単体テストは、開発者がユーザーにコード例を提供することを可能にする、 同時に、その例が有効であることを自動的に検証する。これにより これにより、コードの一部に古いドキュメントが存在するというよくある問題を避けることができる。

宣言の後にドキュメント化されたunittestが続くと、そのunittestの中のコードが挿入される。 のコードは宣言のexample セクションに挿入される:

/// Mathクラス
class Math
{
    /// add関数
    static int add(int x, int y) { return x + y; }

    ///
    unittest
    {
        assert(add(2, 2) == 4);
    }
}

///
unittest
{
    auto math = new Math();
    auto result = math.add(2, 2);
}

上記の場合、次のようなドキュメントが生成される:

クラスMath;
Mathクラス

Example:
auto math = new Math;
auto result = math.add(2, 2);

intadd(intx, inty);
関数" を追加する。

Example:
assert(add(2, 2) == 4);

ドキュメント化されていないユニテストや、プライベートとマークされたユニテストは、コード・サンプルを生成するために使用されない。 コードサンプルの生成には使用されない。

ドキュメント化されたユニテストは複数存在し、どのような順番で表示されても構わない。 をどのような順番で出現させてもよい。それらは最後の非ユニテスト宣言に添付される:

/// add関数
int add(int x, int y) { return x + y; }

/// 生成されたコードサンプル
unittest
{
    assert(add(1, 1) == 2);
}

/// ユニットテストがprivateのため、コードサンプルは生成されない
private unittest
{
    assert(add(2, 2) == 4);
}

unittest
{
    /// ユニットテストがドキュメント化されていないため、コードサンプルは生成されない
    assert(add(3, 3) == 6);
}

/// コードサンプルが生成されたが、コメントしか含まれていない(または空)
unittest
{
    
/** assert(add(4, 4) == 8); */
}

上記の場合、次のようなドキュメントが生成される:

intadd(intx, inty);
add関数".

Examples:
コードサンプルが生成された
assert(add(1, 1) == 2);


Examples:
コードサンプルが生成される。
/** assert(add(4, 4) == 8); */