YahtzeeゲームのTDDスタイルを書いているとしましょう。5つのサイコロのセットがフルハウスかどうかを判断するコードの一部をテストします。私の知る限り、TDDを行うときは、次の原則に従います。
- 最初にテストを書く
- 可能な限り簡単なことを書く
- リファインとリファクタリング
したがって、最初のテストは次のようになります。
public void Returns_true_when_roll_is_full_house()
{
FullHouseTester sut = new FullHouseTester();
var actual = sut.IsFullHouse(1, 1, 1, 2, 2);
Assert.IsTrue(actual);
}
「可能な限り最も簡単なものを書く」に従っている場合、次のようにIsFullHouse
メソッドを記述する必要があります。
public bool IsFullHouse(int roll1, int roll2, int roll3, int roll4, int roll5)
{
if (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)
{
return true;
}
return false;
}
これはグリーンテストになりますが、実装は不完全です。
フルハウスのすべての可能な有効な組み合わせ(値と位置の両方)を単体テストする必要がありますか?これは、IsFullHouse
コードが完全にテストされ、正しいことを確実に確認する唯一の方法のように見えますが、それを行うのは非常に正気に思えません。
このようなものをどのように単体テストしますか?
更新
ErikとKilianは、最初の実装でリテラルを使用してグリーンテストを取得することは最善のアイデアではないかもしれないと指摘します。私がそれをした理由を説明したいと思いますが、その説明はコメントに収まりません。
ユニットテスト(特にTDDアプローチを使用)での実際の経験は非常に限られています。TekpubでRoy OsheroveのTDD Masterclassの録音を見たことを覚えています。エピソードの1つで、彼はString Calculator TDDスタイルを作成します。文字列計算の完全な仕様は、http://osherove.com/tdd-kata-1/にあります。
彼は次のようなテストから始めます。
public void Add_with_empty_string_should_return_zero()
{
StringCalculator sut = new StringCalculator();
int result = sut.Add("");
Assert.AreEqual(0, result);
}
これにより、Add
メソッドのこの最初の実装が行われます。
public int Add(string input)
{
return 0;
}
次に、このテストが追加されます。
public void Add_with_one_number_string_should_return_number()
{
StringCalculator sut = new StringCalculator();
int result = sut.Add("1");
Assert.AreEqual(1, result);
}
そして、Add
メソッドはリファクタリングされます:
public int Add(string input)
{
if (input.Length == 0)
{
return 0;
}
return 1;
}
各ステップの後に、ロイは「最も簡単に機能するものを書く」と言います。
だから、TDDスタイルのヤッツィーゲームをしようとするときに、このアプローチを試してみると思いました。
if (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)