単体テストをレガシー コードに追加したことはありますか? コードはどれほど複雑で、すべてをスタブしてモック化するのはどれほど困難でしたか? 最終結果は価値がありましたか?
8 に答える
私が見つけた最良の方法は、単体テストを段階的に追加することです。ただ飛び込んでアプリケーションの単体テストを行うと言うのではありません。
したがって、バグ修正やリファクタリングのためにコードに触れる場合は、最初に単体テストを作成します。バグの単体テストは、問題を再現できるため、問題の場所を証明するのに役立ちます。
リファクタリングの場合、ユニットテストを書きたいと思うでしょうが、テストを書くことが不可能であることがわかるかもしれないので、リファクタリングされる関数を呼び出す高レベルを見つけて、その部分をユニットテストする必要があるかもしれません. 次に、攻撃的な機能をリファクタリングするときに、テストを作成して、それが正常に動作していることを確認できるようにします。
これを行う簡単な方法はありません。
この質問は、より多くの提案に役立つ場合があります。 大規模なレガシー (C/C++) コードベースに単体テストをどのように導入しますか?
Michael Feather の著書「レガシー コードを効果的に使用する」は、このトピックをカバーする 1 冊の本です。Michael は、レガシー コードはテストできるように構造化されていないため、テストを導入するのは非常に困難であると述べています。私がこの本から最も多く得たのは、「Sprout 関数」と「Sprout クラス」という名前のいくつかのパターンでした。スプラウト関数は、コードで行う必要がある変更をカプセル化する関数です。次に、これらの関数のみを単体テストします。スプラウト クラスは、新しい機能がクラスに含まれていることを除いて、同じ考え方です。
はい、それは一般的に痛みを伴います。代わりに統合テストを書かなければならないことがよくあります。
本The Art of Unit Testingには、これに関する良いアドバイスがあります。また、「レガシー コードを効果的に使用する」という書籍も推奨しています。後者はまだ読んでいませんが、私のスタックにあります。
編集:しかし、はい、最小限のコード カバレッジでも価値がありました。コードをリファクタリングするための自信と安全策が得られました。
EDIT:レガシーコードを効果的に使用するを読みましたが、それは素晴らしいです。
レガシ コードのリファクタリングを計画している場合は、これらの単体テストを作成する必要があります。モックやスタブについて心配する必要はありません。変更やリファクタリングによって現在の機能が損なわれないように、システムの入力と出力のテストについて心配してください。
嘘をつくつもりはありませんが、単体テストをレガシ コードに改造するのは困難ですが、それだけの価値はあります。
無料のオープン ソースのユニット テスト ユーティリティ ライブラリであるApprovalTestsを見てみましょう。あなたが .NET 開発者であれば、作成者である Llewellyn Falco がApprovalTests を使用して新しいコードとレガシー コードの両方の単体テストを改善する方法を示す一連のビデオを作成しています。
単体テストの代替手段の 1 つは、レガシー コードを効果的に使用する方法でも紹介されていますが、特性化テストです。そのようなテストで興味深い結果が得られました。テストできるポイント (シームと呼ばれる) よりもポイントからテストするため、単体テストよりもセットアップが簡単です。欠点は、テストが失敗した場合、テスト対象の領域が単体テストよりもはるかに大きくなる可能性があるため、問題の場所についてのヒントが少ないことです。ここではロギングが役立ちます。
xUnit ファミリーのような単体テスト フレームワークを使用して、特性評価テストを作成できます。
このようなテストでは、事実に基づいて記述され、アサーションがコードの現在の動作を検証します。単体テストとは異なり、コードが正しいことを証明するものではなく、コードの現在の動作を特定 (特徴付け) しているだけです。
プロセスは TDD のものと似ています。
- コードの一部のテストを書く
- 実行する - 失敗する
- コードの観察された動作からテストを修正する
- 実行する - 渡す
- 繰り返す
コードの外部動作を変更すると、テストは失敗します。コードの外部動作? おなじみですね?そうです、ここにいます。これで、コードをリファクタリングできます。
明らかに、リスクは特性評価テストの範囲に依存します。
このプレゼンテーションは、レガシ コードを使用する場合、統合/機能テスト、さらには高レベルの受け入れテストから始めることがなぜそれほど重要なのかという疑問に答えるはずです。そしてゆっくりと、段階的に単体テストを導入します。コード例はありません - 申し訳ありませんが、Michaels Feathers の著書 "Working effective with Legacy Code" でそれらの多くを見つけることができます。
また、Legacy Code Retreat http://www.jbrains.ca/legacy-code-retreatを確認して、お住まいの地域でそのミーティングを探すこともできます。