ユニット/機能テストのない大規模なエンタープライズレベルのアプリケーションがあるとします。非常に厳しい締め切りのため、開発中にテスト駆動の開発プロセスはありませんでした(確信が持てない場合、締め切りを約束するべきではありませんが、何が行われたかがわかります!)
すべての期限が過ぎ、物事が穏やかになった今、皆が私たちを生産的なTDD/BDDベースのチームに変えることに同意しました...そうです!
ここで問題は、私たちがすでに持っているコードについてです:(1)すべてが完全に問題なく(まだ!) ?または、(2)何か問題が発生するのを待ってから、修正中に新しい単体テストを作成するか、(3)以前のコードを忘れて、新しいコードのみの単体テストを作成し、すべてを次の主要なリファクタリングに延期することをお勧めします。
this one などの関連記事がいくつかあります。私たちが非常に限られた時間しかなく、他の多くのプロジェクト/作品が私たちを待っていることを考えると、これに投資する価値があるかどうかはまだわかりません。
注:この質問は、開発チームのまったく厄介な状況を説明/想像しています。これは私や私の同僚のことではありません。それは単なる架空の状況です。これは決して起こらないはずだと思うかもしれませんし、開発マネージャーがそのような混乱の責任を負っています!しかし、とにかく、行われたことは行われます。可能であれば、これは決して起こらないはずだと思うからといって、反対票を投じないでください。
非常に厳しい締め切りのため、開発中にテスト駆動の開発プロセスはありませんでした
この声明は非常に心配です。 TDDなしで開発したという意味でも、すべてをテストしているわけでもありません。これは心配です、それはあなたがTDDがあなたを遅くしそしてあなたが締め切りを見逃すようになると思うのであなたを示すからです。
このように見ている限り、TDDの準備はできていません。 TDDは、徐々に使いこなせるものではありません。あなたはそれを行う方法を知っているか、そうではありません。途中でやろうとすると失敗してしまい、自分らしく見えなくなります。
TDDは、自宅で最初に練習する必要があるものです。 あなたのコードnowを助けるので、それを行う方法を学びましょう。誰かがあなたにそれをするように言ったからではありません。後で変更するときに役立つからではありません。それがあなたがすることになるときなぜならあなたは急いでいるので、あなたは専門的にそれをする準備ができています。
TDDは、anyショップでできることです。テストコードを提出する必要すらありません。他の人がテストを軽蔑するならば、あなたはそれをあなた自身に保つことができます。正しく実行すると、誰も実行していない場合でも、テストによって開発がスピードアップします。
一方、他の人があなたのテストを気に入って実行している場合でも、TDDショップであっても、テストをチェックインするのはあなたの仕事ではないことに注意してください。実績のある実用的な製品コードを作成することです。それがたまたまテスト可能であるならば、きちんと。
管理者がTDDを信じなければならない、または他のコーダーがテストをサポートする必要があると考える場合、TDDがあなたのために行う最善のことを無視しています。これにより、コードの実行内容と実際に実行される内容の違いがすぐにわかります。
それ自体がどのようにして納期をより早く満たすのに役立つのかがわからない場合は、TDDの準備ができていません。家で練習する必要があります。
とは言っても、チームがテストを使用して運用コードを読み取るのを支援できるとき、および管理者が新しいTDDツールを購入するときは素晴らしいことです。
チームをTDDに変換した後、可能なすべてのテストケースを作成することは良い考えですか?
チームが何をしているかに関係なく、可能なすべてのテストケースを作成することは常に良い考えとは限りません。最も有用なテストケースを記述します。 100%のコードカバレッジにはコストがかかります。判断を下すのが難しいからといって、利益の減少の法則を無視しないでください。
興味深いビジネスロジックのテストエネルギーを節約します。決定を下し、ポリシーを施行するもの。それから一体をテストします。単にもの同士を配線するだけの、読みやすくて構造的なグルーコードを退屈にするのは、それほどひどくテストする必要はありません。
(1)すべてが完全に問題なく(まだ!)機能しているにもかかわらず、開発の大部分を停止し、可能な限りすべてのテストケースを最初から書き始めることは、まだ大丈夫ですか?または
いいえ、これは「完全に書き直そう」という考え方です。これは、勝利した知識を破壊します。テストを書く時間を経営陣に求めないでください。テストを書くだけです。いったい何をしているのかがわかれば、テストで速度が落ちることはありません。
(2)何か悪いことが起こるのを待ってから、修正中に新しいユニットテストを書くか、または
(3)以前のコードを忘れて、新しいコードのみの単体テストを記述し、すべてを次の主要なリファクタリングに延期することさえできます。
2と3も同じように答えます。なんらかの理由でコードを変更するとき、テストをすり抜けることができれば本当に素晴らしいです。コードがレガシーである場合、現在テストを歓迎していません。つまり、変更する前にテストするのが難しいということです。まあ、とにかくそれを変更しているので、テスト可能なものに変更してテストすることができます。
それが核オプションです。それは危険です。テストなしで変更を行っています。変更する前に、レガシーコードをテストするためのいくつかの工夫があります。コードを変更せずにコードの動作を変更できるシームと呼ばれるものを探します。構成ファイルの変更、ファイルのビルドなど、必要なことをすべて行います。
Michael Feathersはこれについて本をくれました:レガシーコードで効果的に動作する。それを読むと、何か新しいものを作るために古いものすべてを焼き払う必要がないことがわかります。
ほとんどの開発を停止して、可能な限りすべてのテストケースを最初から書き始めることは、まだ大丈夫ですか、それとも良い考えですか[...]?
遺産を考える1 コード、これらの状況でユニットテストを記述します。
単体テストと同様に、既存のcomplete単体テストスイートを作成します。1 コードベースはおそらく現実的な考えではありません。厳しい納期に間に合うようにあなたを押し進めてきた力。開発中に、適切な単体テストを作成する時間はありませんでした。 「動作するプログラム」のテストを作成するのに十分な時間を与えると思いますか?
1レガシーコードは、単体テストなしのコードです。これは、レガシーコードのTDD定義です。これは、レガシーコードが新しく配信された場合でも適用されます(インクがまだ乾燥していない場合でも)。
私の経験では、テストが役立つために完全なカバレッジを必要としません。代わりに、カバレッジが増加するにつれて、さまざまな種類のメリットを享受し始めます。
真実は、BDDから始めなければ、そこにたどり着くことは決してないからです。なぜなら、コーディング後にテストするために必要な作業は、過度なものだからです。問題はテストを書き込むではなく、さらにaware実際の要件(付随的な実装の詳細ではなく)と、機能的でテストが容易な方法でソフトウェアを設計できること。最初に、またはコードと一緒にテストを作成する場合、これは実質的に無料です。
新機能にはテストが必要ですが、テストには設計変更が必要ですが、リファクタリングにもテストが必要であるため、ちょっとした問題が発生します。ソフトウェアが適切なカバレッジに近づくにつれて、新機能をテストできるようにするためだけに、新機能が発生するコードの部分で慎重なリファクタリングを行う必要があります。これはあなたをかなり遅くします-最初に。しかし、新しい開発が必要な部分だけをリファクタリングしてテストすることにより、テストは、それらが最も必要とされる領域にも焦点を当てます。安定したコードはテストなしで続行できます。バグがある場合は、とにかく変更する必要があります。
TDDへの適応を試みている間、プロジェクト全体のカバレッジよりも優れた測定基準は、変更されるパーツのテストカバレッジです。このカバレッジは最初から非常に高いはずですが、リファクタリングの影響を受けるコードのすべての部分をテストすることは不可能です。また、テストしたコンポーネント内で高いテストカバレッジの利点のほとんどを享受できます。それは完璧ではありませんが、それでもかなり良いです。
単体テストは一般的であるように見えますが、最小のピースから開始することは、レガシーソフトウェアをテストするための適切な戦略ではないことに注意してください。大量のソフトウェアを一度に実行する統合テストから始めることをお勧めします。
例えば。実際のログファイルから統合テストケースを抽出すると便利です。もちろん、そのようなテストの実行には長い時間がかかる可能性があるため、定期的にテストを実行する自動サーバーをセットアップする必要があるかもしれません(例: Jenkins コミットによってトリガーされるサーバー)。テストの失敗が実際にすぐに修正される場合、テストを定期的に実行しない場合と比較して、このようなサーバーのセットアップと保守のコストは非常に小さくなります。
既存のコードのテストを記述しないでください。それはそれだけの価値はありません。
あなたが作ったものはすでに完全に非公式な方法ですでにいくらかテストされています-あなたは常に手でそれを試しました、人々はいくつかの非自動テストを行いました、それは現在使われています。つまり、多くのバグは見つかりませんです。
残っているのはあなたが考えていなかったバグです。しかし、それらはあなたがどちらもユニットテストを書くとは思わないものなので、おそらくまだ見つかりません。
また、TDDを使用する理由は、コードを記述する前に、コードの正確な要件を理解するためです。どんな方法でも、あなたはすでにそれをしました。
それまでの間、これらのテストを作成するのは、事前に作成する場合と同じくらいの作業です。少しの利益のために、それは多くの時間を要します。
そして、その間にコーディングをせずにバグをほとんど見つけることなく、たくさんのテストを書くことは非常にboringです。これを始めると、TDDを初めて使用する人はhateになります。
要するに、開発者はそれを嫌い、マネージャはそれを高くつくと見ますが、多くのバグは見つかりません。実際のTDD部分に到達することはありません。
プロセスの通常の部分として、変更したいものに使用します。
テストは理解を伝える手段です。
したがって、あなたが理解していることだけが真であるべきテストだけを書いてください。
あなたはそれを扱うときに何が真実であるべきかを理解することができます。
したがって、使用しているコードのテストのみを記述してください。
コードを操作するときに学習します。
したがって、テストを作成および書き換えて、学習した内容をキャプチャします。
すすぎ、繰り返します。
テストでコードカバレッジツールを実行し、カバレッジを低下させないメインラインへのコミットのみを受け入れます。最終的には、高レベルのカバレッジに到達します。
しばらくコードを操作しなかった場合は、ビジネス上の決定を行う必要があります。これはおそらく非常に古いレガシーであるため、チームの誰もそれを操作する方法を知りません。おそらく、古くなったライブラリ/コンパイラ/ドキュメントがあり、それはあらゆる点で大きな責任です。
2つのオプション:
(1)すべてが完全に問題なく(まだ!)機能しているにもかかわらず、開発の大部分を停止し、可能な限りすべてのテストケースを最初から書き始めることは、まだ大丈夫ですか?
(2)問題が発生するのを待ってから、修正中に新しい単体テストを作成することをお勧めします
テストの主な目的の1つは、変更によって何も破壊されないことを確認することです。これは3つのステップのプロセスです。
これは、実際にテストを行う必要があることを意味しますbefore実際に何かを変更します。 2番目のパスを選択した場合、つまり、開発者がコードに触れる前にテストを書くように強制する必要があります。そして、私はすでに実際の変化に直面しているとき、開発者がユニットテストにふさわしい注意を払うつもりはないことを強く疑っています。
そのため、開発者が一方の品質を他方の品質に犠牲にしないように、テスト作成タスクと変更作成タスクを分割することをお勧めします。
すべてが完全に機能しているにもかかわらず(まだ!)?
これを具体的に指摘すると、コードが機能していないときにのみテストが必要になるというのは、よくある誤解です。コードが機能しているときにもテストが必要です。たとえば、テストにまだ合格しているため、[新しく発生するバグ]が自分のせいではないことを誰かに証明する場合などです。
すべてが以前と同じように機能することを確認するは、コードが機能しているときにテストが不要であることを暗示するときに省略しているテストの重要な利点です。
(3)以前のコードを忘れて、新しいコードのみの単体テストを作成し、すべてを次の主要なリファクタリングに延期する
理想的には、既存のすべてのソースコードが単体テストを受ける必要があります。ただし、そうするために必要な時間と労力(およびコスト)は、特定のプロジェクトには関係がないという合理的な議論があります。
たとえば、もはや開発されておらず、今後変更される予定のないアプリケーション(たとえば、クライアントがそれを使用しなくなった、またはクライアントがクライアントではなくなった)は、関連性がないと主張できます。このコードをもうテストする。
ただし、線を引く場所は明確ではありません。これは、企業が費用便益分析で検討する必要があるものです。テストの作成には時間と労力がかかりますが、そのアプリケーションの将来の開発を期待していますか?単体テストを作成することによる利益は、それらを記述するコストを上回りますか?
これは、(開発者として)あなたができる決定ではありません。せいぜい、特定のプロジェクトにテストを実装するために必要な時間の見積もりを提供することができ、プロジェクトを実際に維持/開発する必要があるという十分な期待があるかどうかを判断するのは経営者次第です。
すべてを次の主要なリファクタリングに延期します
次の主要なリファクタリングが指定されている場合、実際にテストを記述する必要があります。
しかし、大きな変化に直面するまで、それを延期しないでください。私の最初のポイント(テストの記述とコードの更新を組み合わせない)はまだ残っていますが、ここに2つ目のポイントを追加したいと思います。開発者現在 6つのプロジェクトよりもプロジェクトをよりよく理解していますその時間を他のプロジェクトに費やした場合、数か月かかります。開発者がすでにウォームアップしていて、将来どのように機能するかを理解する必要がない期間を利用します。
私の2セント:
システムの主要な技術的アップグレードを待ってから、テストを書いてください...ビジネスのサポートを得て正式に。
あるいは、あなたがSCRUMショップであり、ワークロードが容量で表され、その%を単体テストに割り当てることができるとしましょう...
テストに戻ってテストを書くつもりだと言うのは素朴ですが、実際に行うのは、テストを書き、リファクタリングし、リファクタリングによってコードがよりテストしやすくなった後、さらに多くのテストを書くことです。あなたがすでに知っているようなテストで、そして...
元の作成者が以前に作成したコードのテストを記述してリファクタリングするのが最善ですが、理想的ではありませんが、経験から、リファクタリングによってコードを改善する必要があります。