テストはどの程度書けば十分ですか?


詳細
テストオーバーライド率100%
これは明らかな答えだ.しかし、これは正しい答えだとは思いません.次の例を示します.

private int[] map = new int[] {
  1, 3, 5, 8};
public int oddNumber(int index) {
  return map[index - 1];
}

簡単なテストを書く

@Test
public void first_odd_number_should_be_one() {
  assertEquals(1, oddNumber(1));
}

このテストは100%のコードをカバーしていますか?カバーされていると思います.しかし、本当にすべての実行パスをテストしたのではないでしょうか.明らかにありません.oddNumber(4)は7のはずですが、このプログラムは8を返します.書き方を変えます.

public int oddNumber(int index) {
  switch(index) {
    case 1: return 1;
    case 2:return 3;
    case 3: return 5;
    case 4: return 8;
  }
  throw new UnsupportedOperationException();
}

書き方を変えた後、テストカバー率はすぐに下がった.違いは,2つ目の書き方では実行経路を字面の静的経路に対応していることである.したがって,テストは完全かどうかの基準を上書きすべきであり,静的経路ではなく動的経路を基準とすべきである.また、最終的にテストカバー率に基づいてテストを補うには、TDDのときと同程度の自信を持たせることはできないことを注意してください.
TWUで学校に通っていたとき、先生は簡単な準則をくれました.
コードを1行増やしすぎて、1行減らしすぎます.
もちろん、先生は英語で教えています.私は意味を中国語で翻訳しました.この言葉は、コードが多くて少なくてはいけないので、すべてのテストを適切に通過させるのが最適だということです.この理屈を検証するために、先生によると、
ThoughtWorks UKの開発者が「コードを削除する」ためのツールを書いた.削除できるコードが1行あれば、すべてのテストに合格できるコードがあれば、削除します.この準則は実務的で、役に立つと思います.また、別の質問にも答えましたが、
すべてのクラスに対応するテストクラスを書いて、すべての動作を上書きしますか?この基準に基づいていないと思いますが、答えは必要ないと思います.あなたのテストがこのクラスのすべての実行パスを上書きすればいいです.このテストがこのクラスに対して独立してテストされたかどうかは、ユニットテストなのか機能テストなのか、ブラックボックステストなのかホワイトボックステストなのかは重要ではありません.重要なのは、このクラスの1行または数行を削除すると、すべてのテストの少なくとも1つのテストに失敗します.これは、あなたのテストがきちんと書かれていることを示しています.
もちろん、疑いと批判の態度を加えます.上のすべての基準に対して、例外があります:それはこの基準がプログラムの正確性に関心を持っているだけで、しかし私はプログラムの行為が正確性と効率から共に構成されていると言います.空っぽの例を挙げます.

if (a) {
 doSomethingUnderConditionA();
} else if (b) {
 doSomethingUnderConditionB();
}

条件AとBは、一致する集合に関係を含む可能性があり、すなわち、1つは別の強い条件である.Aがより強い条件であると仮定すると,より強い条件の場合,より効率的な解を与えることが多い.しかし,条件Aという分岐がなければ,すべての場合条件Bの分岐をたどり,解は依然として正しい可能性がある.すべて,Aの存在はプログラムの正確性に影響を及ぼさず,特定の条件下でのプログラムの効率にのみ影響を及ぼす.では、この場合、コードが1行増えすぎたとは言えません.