LoginSignup
1
0

More than 1 year has passed since last update.

DartでもTableDrivenTests

Posted at

はじめに

Unitテストを書くとき、いろいろなテストケースで書く場合テストコードが煩雑になりがちなことがあるかと思います。

例えば、ログイン状態だとある値を返すけど、非ログイン状態だとnullで返すメソッドのテストをするときや、朝昼夜など時間帯によって結果が変わるようなメソッドの場合など様々なケースでテストを書きたいときはよくあります。

そのときに役立つのがGolangの界隈にあるTableDrivenTestsです。

TableDrivenTestsとは、テストケースをテーブル状に宣言しておいて、あとはそのテストケースを順番にテストコードのパラメータとして流すだけで、可読性も高く網羅的に比較的簡単にテストをかけるようにする手法です。

やっていき

言葉だとイマイチわからないと思うので、実際に紹介していきます。

用意するもの

google.devが公開しているtupleというpackageを使います。
その名の通りTupleのデータ構造を定義できるようになります。

書いてみる

今回はTableDrivenTestsの紹介なので、テストの内容は適当です。
ログイン済みかどうかの isAuthenticatedがtrueかfalseかで挙動が変わるint? sample()のテスト書きたいとします。

tuple packageを使ってるので、Tuple型を使えます。 Tuple7まで対応しているようです。
今回はTuple2を使って、item1にログイン済みかどうかのboolとitem2に期待しているmatcherを格納しています。

void main() {
  // テストケースのテーブル定義
  final testCases = [
    Tuple2(true, 1),
    Tuple2(false, null),
  ];

  // テストケースを順番に実行
  for (final testCase in testCases) {
    test('authenticated is ${testCase.item1}', () {
      expect(sample(testCase.item1), testCase.item2);
    });
  }
}

// サンプル用のメソッド
int? sample(bool isAuthenticated) {
  return isAuthenticated ? 1 : null;
}

今回は純粋にboolによる挙動のみのテストをサンプルに書きましたが、複数のboolで挙動が変わるテストもTuple3を使ってテーブルのパラメータを増やせばかけますし、enumで挙動が変わるものなども可読性高くかけそうです。

どんなテストケースに対応しているかも、テーブル定義を見れば一覧で見れるので、メンテナンス性も高いと感じています。

Dartの今後

今回は、tupleというpackageを使ってTableDrivenTestsを実現しましたが、この機能がDartの言語機能として検討されています。
https://github.com/dart-lang/language/issues/68

そのうちpackageに頼らなくても良くなるかもしれません。

おわりに

複雑なコードのUnitテスト書きたい場合、既存で複雑なテストケースによって煩雑なテストコードになっている場合、ぜひTableDrivenTestsを検討してみてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0