2009-07-03 40 views
8

this answerのコメントの議論のフォローとして、TDDテストは常に失敗するべきですか?TDDテストは常に最初に失敗する必要がありますか?

次の例を考えます。 LinkedHashSetの実装を書いていて、重複を挿入した後に元のものが挿入前と同じ反復順序にある​​という1つのテスト・テストがある場合、重複が全くないという別のテストを追加することができます。

最初のテストは最初に失敗してから実行されることが確認されます。

問題は、最初のテストパスを作成するために、実装は、データを格納するために、異なるセットの実装を使用することは非常に可能性があるので、ちょうど副作用として第二のテストが既に通過することです。

私は、テストの失敗の主な目的は、テストが良いテストであることを保証することだと思います(何度もテストを書いてしまいました。 。しかし、あなたが書いたテストが本当に何かをテストしていると確信しているなら、あとでその行動を破らないようにすることは貴重なことではありませんか?

+0

私は確かに、動的言語のルーキー(したがって、答えではなくコメント)ですが、私の直感は動的言語の場合はそうです。静的言語に依存します。静的言語でコンパイルが失敗するコードは動的言語で実行されますが、テストは失敗します。静的な言語を実行するためには、テスト中のコードに何らかのベースライン動作を追加する必要があります(たとえ空のメソッドであっても)。正しく書き込まれたテストを最初に通過させる必要があります。 –

答えて

9

もちろん、それは役に立ちますregression testですので、それは貴重です。私の意見では、回帰テストは新しく開発されたコードをテストするより重要です。

最初に必ず失敗しなければならないと言うのは、実用性を超えたルールです。

4

私のためのTDDは設計ツールの多くであり、後の考察ではありません。だからこそ他の方法はありません。テストをパスするコードがないので、テストは失敗します。テストをパスした後でなければ、テストは失敗します。

6

はい、緑色(作業中)になる前にTDDテストが失敗する必要があります。そうでなければ、あなたは有効なテストがあるかどうかわかりません。

+0

私は同意しません - some_value_should_always_be_false()のようなテストをしている静的言語をとってください。意図的にテストを妨害し、テスト対象の値をtrueに設定しない限り、テストをコンパイルするのに十分なコードを書くだけでテストに合格するでしょう。 –

+2

したがって、OPで提示されたようなシナリオにどのように対処していますか? – Yishai

+1

@Jeremy Frey - 初期テストを失敗させるためにテストを妨害しないようにしてください。目標は言語そのものではなく、ロジックをテストすることです。あなたが言及した例では、値が常にfalseであると見なすことができれば、テストは値を追加するのはあまりにも簡単です。私はこれが役立つことを願っています –

4

「最初に失敗する」という点は、テストがうまくいったことを冗談に感じないようにすることだと思います。異なるパラメータで同じメソッドをチェックする一連のテストがある場合、そのうちの1つ(または複数)が最初から渡される可能性があります。あなたが適切にコードを実装する必要がありますので、これらのテストの

public void testDoFoo_matches() { 
    assertEquals("Geoff Hurst", createBar().doFoo(1966)); 
} 

public void testDoFoo_validNoMatch() { 
    assertEquals("no match", createBar().doFoo(1)); 
} 

public void testDoFoo_outOfRange() { 
    assertEquals(null, createBar().doFoo(-1)); 
} 
public void testDoFoo_tryAgain() { 
    assertEquals("try again", createBar().doFoo(0)); 
} 

一つが通過しますが、明らかに他の人はいないでしょう。何かのように

public String doFoo(int param) { 
    //TODO implement me 
    return null; 
} 

テストは次のようになります。この例を考えてみましょう合格する一連のテスト。私はそれが本当の必要条件だと思う。ルールの精神は、ハッキングを開始する前に予想される結果について考えていることを確認することです。

+0

@ジョンあなたは何を変えましたか?前と後は同じ私を見て –

+0

@リッチ:彼はいくつかのかっこを追加しました。 「編集済み」の横にあるリンクをクリックすると、どれぐらい前に編集されたのか(名前のすぐ上に)、すべての相違点と編集メモが表示されます。 –

+0

@Ahmad、それは私が行ったことですが、取り消し線と新しいテキストが同じであることを伝えることができる限り(書式なしで最初の変更を下にコピーして貼り付けます)createBar()。doFoo(1966)createBar()。 doFoo(1966)。何が私が逃した –

0

IMHO、最初に失敗することの重要性は、作成したテストに欠陥がないことを確認することです。たとえば、あなたのテストでAssertを忘れることができますし、おそらくそれを知ることはできません。

似たようなケースでは、境界テストをやっているとき、あなたはそれをカバーして、コードをすでに構築した発生し、それをテストすることをお勧めします。

私はあなたのテストが失敗しないようにするために大きな問題ではないと思っていますが、本当にテストしていることを確かめなければなりません。

1

のテストを検証して、有効なものであることを検証し、意図していることをテストする方法が実際に求められています。

それが最初に失敗作ることはOKオプションですが、それはあなたが失敗することを計画する際に失敗し、あなたはそれを成功させるためのコードをリファクタリングした後、成功しても、まだということは意味しないことに注意してください、あなたのテストあなたが望むものを実際にテストしました...もちろん、あなたのテストをテストするために別の振る舞いをするいくつかのクラスを書くことができます...しかし、それは実際にあなたの元のテストをテストするテストです - 新しいテストが有効であることをどうやって知っていますか? :-)

テストを最初に失敗させることは良いアイデアですが、まだ完全ではありません。

関連する問題