TESTコードをテストするにはどうすればよいですか?


22

ほとんどのソフトウェア開発者が同意する数少ない点の1つは、テストしない限り、正しく動作するためにコードに依存すべきではないということです。あなたがそれをテストしないなら、それはあなたが将来さらに仕事をすることになるだけの隠れたバグを持っているかもしれません。

通常のコードのテスト方法は理解していますが、テストコードをテストして、エラーが存在する場合に効果的にエラーを見つけて報告できることを確認するにはどうすればよいですか?私は個人的には、あるべきではないときに合格する誤ったテストケースを書くほど愚かであり、そもそも筆記テストの目的を破っています。幸いなことに、私は時間内にエラーを見つけて修正しましたが、テストのマントラによれば、それが機能することを確認するための独自のテストセットがなければ、テストスイートは完成しないようです。

これを行うための最良の方法は、バグのあるコードのテストが失敗することを確認することだと思われます。テストは「動作」します。これにより、2番目の質問が表示されます。テストケースでバグを確実にキャッチするために、バグを導入する良い方法は何ですか?文をランダムにコメントアウトしif-else、条件を否定して間違ったブランチを実行することを確認し、副作用などでコードの実行順序を変更して、テストが最もキャッチされるようになるまで一般的なバグ?プロの開発者は、テストが実際に行うべきことを実際に行うことをどのように検証しますか?彼らは単にテストが機能すると仮定していますか、それともテストにも時間をかけていますか?もしそうなら、彼らはどのようにテストをテストしますか?

私は、人々がテストをテストし、実際に実際のコードを書くことのないテストのためにテストをテストするのにそれほど多くの時間を費やすべきだと提案しているわけではありませんが、 「メタテスト」の、そしてそれを行うための最良の方法に興味がありました。:D

*「バグのない」コードをテストするときにテストが合格するかどうかを確認できましたが、テストの仕様としてコードを使用することはかなり逆に思えます...


ユニットテストに自信がないように思えますが、これはおそらく、テストを書く経験が豊富ではないためでしょうか?その場合、より多くのテストを記述し、異なる結果を期待するのは不合理です。ちょうどあなたがやっていることをやり続け、できる限り徹底的に(失敗と成功のテスト)してください。そうすれば、ユニットテストはすぐに成果を上げ始め、それらに対する信頼が高まります。
-MattDavey


より多くのツールを使用する前に、実際のツールをよりよく使用してください。より少ないテストを書きますが、より効率的で、より良いテストを書きます。理解できないものを信頼することはできません。
スティーブチャマイラード

回答:


16

TDDの標準フローは次のとおりです。

  1. 失敗したテストを記述します。(赤)
  2. 合格する最小のコード変更を行う(緑)
  3. リファクタリング(緑色を維持)

この場合のテストのテストはステップ1です。コードを変更する前にテストが失敗することを確認します。

私が気に入っているもう1つのテストは、一部のコードを削除して別の方法で再実装できるかどうかです。テストは削除後に失敗しますが、別のアルゴリズムで動作します。

すべてのものと同様に、魔法の弾丸はありません。必要なテストを書くのを忘れるのは、コードを書くのを忘れるのと同じくらい簡単に開発者にとってできます。少なくとも両方を行っている場合、あなたは自分の脱落を発見する機会が2倍あります。


4
二重簿記:ユニットテストは製品コードをテストし、その逆も同様です。それらは、同じ問題を述べる2つの異なる方法です。二重簿記のように、2つの異なる方法でトランザクションを記録し、両方が同じ合計を取得する必要があります。
EricSchaefer

問題は、コードにまだバグがあるにもかかわらず、手順2でテストがグリーンになったときの問題です。簡単な例:空でないリストオブジェクトへのポインターを返す必要がある関数があります。テストでは、ポインターがnullステップ1で失敗するかどうかをテストします。空のリストを返すことで、ポインターが通過する最小のコード変更を行います。2つのバグがあるため、テストは「グリーン」になりました。
クリスチャンハックル

@ChristianHacklはその開発段階で完璧な実装です!予想される動作をさらに詳細に指定するには、最初に失敗する1つ(または複数)のテストを追加する必要があります。続いて、これらのテストを環境に合わせて実装します。
アンディ

@Andy:コードとテストの両方にバグがあり、一方が他方に気付かないようにするときに、これがどのように完璧な実装であるかを詳しく説明するように注意してください。(コードのバグは空のリストが返されることであり、テストのバグはnull空をチェックすることであり、空ではないことです。)
Christian Hackl

@ChristianHacklあなたは空のチェックに従って正しいです。実際、それはテストでも行われるべきです。要件をテストに段階的に翻訳すると、バグの余地がほとんどなくなります。仕様に固執しない場合を除きます(空でないチェックを見落とすなど)。
アンディ

9

1つのアプローチは、Jesterなどのツールを使用した突然変異テストです。

Jesterはコードにいくつかの変更を加え、テストを実行します。テストに合格すると、Jesterは変更内容を示すメッセージを表示します


4

テストのためのテスト?その道に行かないでください。その後、おそらくテストのためのテストのためのテストが必要になり、テストのためのテストのためのテストのためのテストが必要になるでしょう...どこでやめますか?

通常のテストフローは次のようになります。開発者は、時間の大半をポイント1〜3に費やします。

  1. コード
  2. 単体テスト
  3. 統合テスト
  4. システム/その他の自動化
  5. QA /ヒューマンテスター

コードにバグを交互に追加するのに2分かかる場合(...)

あなたのコードは最終的に自身のバグを「成長」させ、それらを手作業で導入する時間を無駄にしないでください。言うまでもなく、あなたが前もって知っていたことは本当にバグですか?バグが来るでしょう、私はそれを心配しません。

文をランダムにコメントアウトする場合、if-elseの間違ったブランチが条件を否定することによって実行されることを確認してください(...)

これは実際に、自分が考えていることを実際にテストするかどうかを検証するための実行可能なアプローチです。「テストのためのテストのためのテスト」と同じ問題に苦しんでいるので、常にそれほど良いとは思いません。テストしているコードが100%動作していることを知ってコードの変更を停止するのはいつですか?

また、昔からの実用的なプログラマーのアドバイスを覚えておくことも良いことです。あなたはそれを必要としないでしょう。アジャイルになり、実際のバグのテストとコードを記述します。代わりに、表示される場合と表示されない場合がある仮説のテストを記述します。


3
私は自分のコードにバグが増えることを心配していません。テストが発生したときにそれらをキャッチすることを心配しています。私のテストに欠陥がある場合、彼らは仕事をせず、実際にまだ存在している特定のクラスのバグを取り除き、不正確なテスト結果を見ているので私の仕事を難しくしていると思います(失敗する場合に合格)。
ゴードンガスタフソン

@CrazyJugglerDrummer:あなたのテストは確かにすべてのバグをキャッチしません。彼らはその目的にかなうものではありません-これがQAの出番です。もしそうするなら、ソースコードが変更されない限り、ソフトウェアにバグがないことを意味します。
キロ

3

構造上、機能コードとテストコードは互いにテストされます。1つの問題が残っています。機能コードのバグがテストコードのバグによって隠されている場合のコモンモードバグの場合です。TDDはこの影響を受けません。これが、この確率を減らすために、通常、異なる人々によって複数のレベルでテストが実行される理由です。


0

単体テストは、デバッガーで作成するときに1回テストします。それからあなたはそれを放っておいて、それを忘れます。ここで問題はありません。

このことを考慮。単体テストの目的は何ですか?メインプログラムで行う多数の変更のいずれかが、そのプログラムのロジックを誤って変更した場合に通知します。どんな変更でも潜在的に何かを壊すことを知っているので、あなたはそれを持ちたいです。テストをテストしなくても問題がないのはそのためです。プログラムのロジックを意図的に変更するまでテストを台無しにしないでください(テストを再訪してもう一度テストする必要があります)。テストが誤って破損する可能性はありません。


-2

検査の適合性と品質を評価および測定する突然変異検査があります。

これを使用して、「テスト」自体を評価できます。

簡単に言えば、TestAがコードとその突然変異コード(元のコードと非常に似ているがわずかに異なるコード)の違いを見つけることをテストすることで、テスト(TestAなど)を評価できます。

TestAがコードとその突然変異コードの違いを見つけることができない場合、それはTestAが元のコードをテストするにはあまりにも粗い規制を持っていることを意味します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.