私のチームは、テスト駆動開発への移行を検討しています。現在、単体テストはほとんどなく、ユーザー受け入れテストと開発者自身の手動テストのみに依存しています。誰もがこの提案に同意したわけではない。チームでは、ユニットテストの経験は実際には誰もいないので、それを行うことのメリットを全員に納得させることは困難です。異論の1つは、必要な時間です。
私の質問は、タスク自体に比べて、単体テストを追加するために通常どれだけ余分な時間が必要かということです。タスクのコーディング(受け入れテストを除く)が半日かかる場合、単体テストは平均でどのくらいの時間がかかりますか?この見積もりは、単体テストを行うことの相対的な利点を説明し、計画を調整するために重要です。
重要なのは、主に.NETデスクトップアプリケーション(GUIとデータベースを使用)で作業していることであり、安全性が重要ではありません(つまり、原子力発電所やそのようなものではありません)。また、私たちの誰も経験がないので、学習曲線があります
通常使用する開発プロセス、チームの経験、さらに重要なのは、手元にあるタスクの複雑さをよく理解せずに明確な答えを提供することは困難です。これには、おそらく、メソッドの一般的な記述方法と行った設計の選択も追加する必要があります。
単体テストは常に開発に時間を追加します。コードを適切にテストしている場合は、実装コードよりもテストの作成に多くの時間を費やす必要があります。これは最初は非常に恐ろしいように聞こえ、おそらく多くの人がそもそも単体テストを避けようとする主な理由の1つでしょう。私の現在の職場でさえ、オーバーヘッドのテストに関する懸念が長期的なメリットを完全に理解していないためだと皆に納得させるのに4年以上かかりました。
短期的に、特に初めてユニットテストを開始したときに、開発時間が大幅に遅くなることがわかります。これは必要な学習期間です。ほとんどの開発者は、ユニットテストをどこに適用するかを選択するか、最初にコードを記述し、実装が本質的に完了した後でテストを適用します。そうすることで、実装コードの変更を必要とし、その後のテストの変更を必要とするバグを見つけます。これは非常に非生産的なプロセスであることが判明し、ほとんどの開発者は、常にテストに追いついているのではないかと迷うでしょう。実際のひらめきは、開発者が完全なテストのコーディングを開始したときに発生しますbefore実装コードを記述します。これは、生成されるコードがより簡潔になり、記述がはるかに速くなるためです。
最初のテスト方法の利点は、テストが実装コードがテストの条件を満たすために書かれたまさにその瞬間に機能することを示すという事実にあります。さらに、実装コードが比較的簡潔に保たれている場合は、テストで変更するのが簡単になる可能性が高く、最初にテストする本当の利点を提供します。これは、コードが実行された正確な瞬間を識別するシステムの保証です。エラーを含むように変更されました。すでに用意されているテストをサポートすることで、コードの変更がはるかに簡単になり、メンテナンスのオーバーヘッドが大幅に削減され、デバッグの労力が大幅に軽減されます。
単体テストと最初のテストに非常に慣れている場合は、タスクの見積もりがより簡単になり、バグとそれに続くデバッグ作業の見積もりが原因で発生する長く予期しない遅延によって混乱することがなくなります。 、潜在的なバグの大部分は、単にテストを中心に開発作業を集中することで対処されていることがわかります。以前にユーザー受け入れテスト期間中に長いデバッグプロセスを処理していたことに気付いた場合、将来的には実装後のデバッグフェーズを見つけ、ユーザー受け入れテストにかかる時間が大幅に短縮されます。
したがって、実際の問題は、テストに追加される時間の量が少なくなること、および製品のデバッグと保守に費やされる実装後の短い時間と実装後の短い時間のトレードオフ、およびテストスイートがどのように役立つかについての詳細になります。コードベースの任意の部分を変更するときが来たとき。さらに重要なことは、これらすべてがビジネスにとって真に測定可能な価値にどのように変換されるかです。私が話していることの非常に大まかな例として、チームが最初にユニットテストを真剣に書き始めたとき、私は製品のモジュールを開発するためにバグの問題と時間に関するいくつかの測定を行い、時間の比較を追加しました新しい開発とメンテナンスの問題に取り組んでいます。最初の単体テストをテストする前は、メンテナンス作業は開発作業の3倍でしたが、最初に完全に単体テストに移行したプロジェクト(および数か月の経験の後)では、新しい開発作業に費やした作業は、作業よりも大きくなりました。メンテナンスに費やした。これは、実質的なドルの価値を付け加えれば、かなりの節約になります。つまり、チームはより多くの現金を費やしたり、リソースを活用したりする必要なく、より多くの仕事を引き受けることができました。
これが自分の作業環境に正確にどのように変換されるかを具体的に予測することは困難です。私は、数人がメソッドチャンピオンとして行動し、しばらくの間はテストファーストの方法で作業して、それがどのようになるかを実際に感じることをお勧めします作業環境に適合します。 1つの提案は、少し実験的な開発を行うことです。数人の人に2、3の同様のタスク(または時間を割り当てる余裕がある場合は同じタスクを複製する)に少しの間働きかけてもらい、実装時間と完了後のデバッグ時間の違いを確認します。また、コードレビューを実施して、各タスクの進行に伴うコード品質の問題を調査します。少し時間をかけて、チームの反対意見が減るか、強くなるかを確認します。
個人的には、ユニットテストを行うべきではない理由は考えられませんが、私はあなたの特定の環境では働いていないため、実際に話すことはできません。単なる練習。これは、うまく使用すれば素晴らしい結果が得られるツールですが、チーム全体がツールを使用できない場合、またはツールの使用によってチーム内で障害のパターンが発生する場合、そのツールはおそらく機能しません。あなたに合っている。あなたが確実に知ることができる唯一の方法は、それを試し、自分自身で見ることです。
私の経験では、単体テストではそれほど時間はかかりません。実際、実装時間を節約できます。テスト可能なようにコードを書くと、より明確でモジュール化されたコードを書く傾向があり、より正確であると確信できます。また、テストした場合に正確であることを証明し、メソッドの呼び出しをどのように意図するかを示すテストにもなります。
チームの誰もまだ多くのテスティングの経験がないとあなたは言いました。誰もがツールに自信を持ち、何が優れたテストになるかが確信できるようになるまでには、少し時間がかかります。私が協力しているチームでは、私たち全員がコードをテスト可能なチャンクに分割する方法を完全に理解するまでに約2か月かかりました。私たちが抱えていた最大の課題は、データベースマネージャーなどの外部の依存関係をテストのために注入できるように、クラスに継ぎ目を残すことを学ぶことでした。しかし、結果はそれだけの価値がありました。データベース接続の詳細を、それを必要とするコードから分離しておくという明確なパターンになりました。 DBスキームを変更する必要がある場合でも、影響を受ける領域を1つのレイヤーに制限することができました。それだけでなく、DBへのすべての参照は、IDEを使用してすばやく見つけることができます。