Tips 単体テスト可読性UP方法
ASP.NET Fall 2012 Update が気になるところですが…
単体テストについてです。
可読性UP!
expect(予想値)と、actual (結果値) を明確にして書くと、
テストがわかりやすくなるとよく言われますが、
もう一歩進んで、
- expect(予想値)
- actual (結果値)
- もう1つ、実行メソッド
これら3つの距離を視覚的に近くして、
そして更に、
- 関連のあるテストケースを近くに集める
と可読性がUPします!
わかりにくい例
例えば下のようなメソッドの単体テストを書く場合は、
//テスト対象メソッド DateTime? ToNullableDate(string input);
こんな書き方があると思います。
//一般的な文字列から日付への変換テスト { String input = "2012/03/01"; DateTime? expect = new DateTime(2012, 3, 1); DateTime? actual = DateHelper.ToNullableDate(input); Assert.AreEqual(expect, actual); } //空文字が指定されたら、Null を返しているかのテスト { String input = String.Empty; DateTime? expect = null; DateTime? actual = DateHelper.ToNullableDate(input); Assert.AreEqual(expect, actual); }
綺麗に書かれているのですが、この書き方は連続して書かれると、
わかりにくくなる、という欠点があります。
なぜかというと、2つのテストケースが結構離れているからです。
実行メソッドの仕様が、複数のテストケースによって把握できるものである場合、
この方法はちょっとわかりにくくなります。
他の方法である、Nunit の TestCase を使っても・・・↓
//ToNullableDate のテストケース object[] toNullableDate_TestCase = new object[] { new object[] { "2012/03/01", new DateTime(2012, 3, 1)}, new object[] { String.Empty, null } }; [Test] [TestCaseSource("toNullableDate_TestCase")] public void ToNullableDate_Test(String input, DateTime? expect) { DateTime? actual = DateHelper.ToNullableDate(input); Assert.AreEqual(expect, actual); }
テストケースが並べられ良い感じになりましたが、
Nunit の TestCaseSource には、テストケースの値がどういう値なのか、わかりにくい
という欠点があります。
わかりやすい書き方
デリゲートと、Nunit の That 記法を使って、
3つの距離を小さくして、テストケースをまとめると・・・
Func<String, DateTime?> execute = (input) => DateHelper.ToNullableDate(input); Assert.That(execute("2012/03/25"), Is.EqualTo(new DateTime(2012, 3, 25))); Assert.That(execute(String.Empty), Is.Null); Assert.That( () => execute("invalidValue"), Throws.Exception);
どうでしょう!?
わかりやすくなりました!?