私は自分のワークグループでユニットテストを提唱しようとしていますが、私がよく受ける反対意見は、外部エクスポートされたAPI(これはシステムの最小限かつ重要ではない部分のみ)にのみ使用すべきであり、内部およびプライベートでは使用しないことですコード(機能テストのみになりました)。
ユニットテストはすべてのコードに適用できるし、そうすべきだと思いますが、同僚をどのように説得できますか?
私は自分のワークグループでユニットテストを提唱しようとしていますが、私がよく受ける反対意見は、外部エクスポートされたAPI(これはシステムの最小限かつ重要ではない部分のみ)にのみ使用すべきであり、内部およびプライベートでは使用しないことですコード(機能テストのみになりました)。
ユニットテストはすべてのコードに適用できるし、そうすべきだと思いますが、同僚をどのように説得できますか?
回答:
あなたの同僚は、本当の単体テストと統合テストを混同しているかもしれません。製品がAPIである(またはAPIを持っている)場合、統合テストはNUnitテストケースとしてプログラムできます。一部の人々は、それらがユニットテストであると誤って信じています。
次の方法で同僚を説得することができます(このことを既に知っていると確信しています。同僚にそれを指摘するだけで助けになるかもしれません)。
内部/プライベートコードで単体テストを使用する理由は、外部でサポートされているAPIの場合とまったく同じです。
あなたが私があなたがそれを意味すると思う方法でプライベートを意味するなら、いいえ-あなたはそれをユニットテストするべきではありません。観察可能な動作/状態の単体テストのみを行う必要があります。TDDの「赤-緑-リファクタリング」サイクルの背後にあるポイントを見逃している可能性があります(最初にテストを行っていない場合は、同じ原則が適用されます)。テストが作成されて合格すると、リファクタリングを実行している間にテストが変更されないようにします。プライベート機能の単体テストを余儀なくされている場合は、おそらく公開機能に関する単体テストに欠陥があることを意味します。パブリックコードの周りにテストを書くのが難しくて複雑な場合は、クラスが多すぎるか、問題が明確に定義されていない可能性があります。
さらに悪いことに、ユニットテストは時間の経過とともにボールとチェーンになり、価値をまったく追加せずに速度が低下します(最適化や重複の削除など、実装を変更してもユニットテストに影響はありません)。ただし、内部コードは、動作/状態が(制限された方法で)観察可能であるため、ユニットテストする必要があります。
ユニットテストを初めて行ったとき、私はあらゆる種類のトリックを使ってプライベートなものをユニットテストしましたが、今では、数年後には時間の無駄よりも悪いと感じています。
ここにちょっと馬鹿げた例がありますが、もちろん実際にはこれらよりも多くのテストがあります:
文字列のソートされたリストを返すクラスがあるとしましょう-結果が実際にそのリストをソートする方法ではなく、ソートされていることを確認する必要があります。リストをソートするだけの単一のアルゴリズムで実装を開始できます。それが完了したら、並べ替えアルゴリズムを変更しても、テストを変更する必要はありません。この時点で、単一のテストがあります(ソートがクラスに埋め込まれていると仮定):
2つのアルゴリズムが必要だとすると(おそらく1つは状況によってはより効率的ですが、他のアルゴリズムはそうではありません)、各アルゴリズムは異なるクラスによって提供され(一般的にはそうである必要があります)、クラスはそれらから選択します-これが起こっていることを確認できますモックを使用して選択したシナリオですが、元のテストはまだ有効であり、観察可能な動作/状態を確認するだけなので、変更する必要はありません。最終的に3つのテストになります。
別の方法は、クラス内でプライベートコードのテストを開始することです。これからは何も得られません。上記のテストは、ユニットテストに関する限り、知っておく必要のあるすべてを教えてくれます。プライベートテストを追加することで、自分でストレートジャケットを作成できますが、結果が並べ替えられたことだけでなく、並べ替え方法もチェックした場合、さらに多くの作業が必要になります。
(このタイプの)テストは、動作が変更されたときにのみ変更され、プライベートコードに対するテストの作成を開始する必要があります。
時間の無駄(「別の金makingけプロジェクトをコーディングできたかもしれません!」)または再帰的(「そして、テストケースのテストケースを書く必要がある!」)私は両方を言って有罪です。
初めてバグを発見したとき、あなたは完璧ではないという真実に直面しなければなりません(プログラマーがどれほど早く忘れるのか!)、そして「うーん」と言います。
単体テストのもう1つの側面は、テスト可能なコードを作成する必要があることです。一部のコードは簡単にテスト可能であり、一部のコードは優れたプログラマーを「うーん」とは思わないことに気づきます。
ユニットテストが外部向けAPIにのみ役立つ理由を同僚に尋ねましたか?
単体テストの価値を示す1つの方法は、厄介なバグが発生するのを待ってから、単体テストがどのようにそれを防ぐことができたかを示すことです。それは彼らの顔にそれをこすり付けることではなく、彼らの心の中で、ユニットテストをアイボリータワー理論から溝の中の現実に移すことです。
別の方法は、同じエラーが2回発生するまで待つことです。「うーん、ボス、先週の問題の後にヌルをテストするコードを追加しましたが、今回はユーザーが空のものを入力しました!」
例でリード。コードの単体テストを作成し、上司に値を示します。その後、上司がいつか昼食のためにピザを呼び出してプレゼンテーションを行うかどうかを確認します。
最後に、prodにプッシュしようとしているときに感じる安心感を伝えることはできません。ユニットテストから緑色のバーが表示されます。
プライベートコードの2種類があります:公共のコード(またはパブリックコード(または...)によって呼び出される民間のコードによって呼び出されるプライベートコード)によって呼び出される民間コードとプライベートコードず、最終的に公衆によって呼び出されませコード。
前者はすでに公開コードのテストでテストされています。呼び出されない後者缶まったくひいてはがテストされていない、削除する必要があります。
TDDを実行すると、テストされていないプライベートコードが存在することは不可能であることに注意してください。
ユニットテストとは、コードのユニットをテストすることです。ユニットが何であるかを定義するのはあなた次第です。同僚は、ユニットをAPI要素として定義します。
とにかく、APIをテストすると、プライベートコードも実行されるはずです。コードカバレッジを単体テストの進捗状況の指標として定義すると、すべてのコードをテストすることになります。コードの一部に到達していない場合、同僚に3つの選択肢を与えます。