すべての可能性をテストすることはできませんが、少なくともコードで考慮されている可能性をテストする必要があります。
したがって、メソッドに渡される文字列が 8 文字を超えてはならない例では (ちなみに、これはパスワードの厳しい要件です)、メソッドは次のようになります。
public bool IsPasswordCorrect(string password)
{
if (password.Length > 8)
throw new ArgumentException("Password must not be greater than 8 characters.");
return password == SomeKnownPassword;
}
目標は、100% のコード カバレッジにする必要があります。つまり、実際に何かを実行するコードの各行には、少なくとも 1 つの対応するテストが必要です。したがって、唯一のテストが「ハッピー パス」(8 文字以下の文字列) の場合、そのthrow
行はテストされません。
そのコード行は要件に対応するものであるため、その要件をテストする必要があります。この場合、いくつかのテストがあります。
[TestMethod]
public void MatchingPasswordsShouldBeAllowed()
{
// set the known password
// set the passed password
// call the method
// assert that the method returned true
}
[TestMethod]
public void NonMatchingPasswordsShouldNotBeAllowed()
{
// set the known password
// set the passed password to something else
// call the method
// assert that the method returned false
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void PasswordsShouldNotBeGreaterThanEightCharacters()
{
// set the known password
// set the passed password to something too long
// call the method
// assert that an exception was thrown
}
テスト メソッドの名前に注意してください。それらは要件のように聞こえます。この考え方は、規定された要件を実際の仕様に分解する必要があるというものです。ビジネス要件は次のとおりです。
しかし、そこに暗黙の要件はありますか? 次のような要件:
- 既知のパスワードと一致する提供されたパスワードにより、認証が行われます。
- 既知のパスワードと一致しない提供されたパスワードは、認証につながるべきではありません。
結局のところ、メソッドはこれらすべてのことを行っています。メソッドが何かを実行している場合は、その何かをテストする必要があります。最終的に、コードが行うすべてのことは、要件に対応する少なくとも 1 つの対応するテストを持つ必要があります。
実際、テストが適切に作成されていれば、要件になり始めます。問題の知識 (要件) を複数の異なる場所 (テスト、コード、ドキュメント、ホワイトボードなど) ではなく 1 つの場所 (テスト) に保持できるため、これは良いことです。
テストによって実行されないコード行がある場合、なぜそのコード行があるのでしょうか? それに対するテストがない場合、それに対する要件はありません。要件がない場合は、削除してください。