十分な量の単体テストでカバーされたコードベースがあるとします。コードに小さな変更を加え、テストがまだ成功しているかどうかを確認したいと思います。変更の影響を受けるテストだけを再実行できるとしたらすばらしいと思いませんか。影響を受けるテストのリストを作成するために必要なすべてのデータが揃っているようです。VCSから変更された行のセットを取得でき、ソースコード行から対応するテストへのマッピングは、カバレッジ統計から決定できます。
既存の単体テストフレームワークのいずれかがそのような手法をサポートしていますか?
更新。ポイントは、迅速なフィードバックを得ることです。もちろん、CIは完全なスイートを実行できますし、実行する必要があります。
いいえ、それは良い考えではありません。
テストスイートのポイントは、開発がどこにも欠陥をもたらさないことを保証することですwithoutプログラムのどの部分がどの部分に影響するかについて推論する必要があります。単体テストが非常に遅いため、すべてを実行したくない場合は、必然的に遅かれ早かれそれらの実行を停止し、それらがもたらす利点を失うことになります。その時点で、彼らは資産になるのをやめて純粋な責任になります:彼らは努力を要し、表に価値をもたらしません。その道を下ってはいけない。
はい、これはより関連性の高いテスト結果をより迅速に取得するのに役立つ既知の手法です。影響を受ける可能性のあるテストを選択するだけでテスト結果が脆弱になるという穏やかな欠点は、この情報を使用してテストの順序を決定するだけで回避できます。これにより、テストが合格とマークされる前に完全なテストスイートを実行する必要がある一方で、テストの失敗がすぐに報告される可能性が高くなります。
ただし、これには、テストごとのカバレッジデータと、このカバレッジデータを使用できるテストランナーが必要です。これを実現できるツールチェーンは、特にオープンソースの世界では非常にまれです。のように:私は実際にこれを実装するそのようなツールを知りません。カバレッジに使用する粒度に応じて(たとえば、テストごととテストスイートごと、またはラインごとと関数カバレッジごと)、これもかなりの量のストレージを必要とする可能性があります。
最後に、ソースコードへの多くの変更では、この変更を正しいテストに関連付けることができないという実際的な問題があります。たとえば、追加コードを実行するように制御フローを変更しても、この追加コードのテストは見つかりません。さらに悪いことに、実行時に実行されず、そのためカバレッジのないコード(型宣言など)を変更すると、広範囲にわたる影響がありますが、テストは選択されません。
実際には、ほとんどのテストスイートが行うことは、カバーするコードによってテストを編成することです。 _class Foo
_のテストはFooTest
にあります。この関連付けにより、カバレッジデータが不要になります。テストには、特定の種類のテストを含めたり除外したりできるタグが付いている場合もあります。これにより、ユーザーがtest (FooTest or BarTest) and not #slow
などの適切なテストサブセットを手動で選択できるようになる場合があります。それが、私が遅いように見えるテストスイートを処理するために行うことです。適切な注意を払えば、選択はスクリプトで行うこともできます。
はい。 JavaScriptの場合 https://wallabyjs.com/
彼らのホームページから:
コード変更の影響を受けるテストのみを実行し、並行してテストを実行するため、このツールは非常に高速です。
私があなたの説明に最も近いのは、ユニットテストランナー内の ReSharper 機能です。
疑問符の付いた緑色の目盛りは、前のセッションで合格したが現在は古くなったと見なされるテストを示します。
これは素晴らしい機能ですが、信頼できるほど信頼できる機能はありません。私は、これまで取り組んできた一般的な領域ですべてのテストを実行することを好みます。
一部の開発者は、変更がローカルで行われるたびにすべてのテストを実行することを好みますが、コードベースに精通している場合は、メインブランチ(理想的には、それ自体が完全な単体テストの実行をトリガーします)。
ほとんどの単体テストフレームワークには、選択した一連のテストを実行する機能があります。たとえば、Mocha/Chaiを使用するJavascriptでは、「describe.only」を実行できます。
新しいコードやテストを追加する場合、特にこれらの特定のテストのみを短期間に実行したい場合があるため、これは(特に多数のテストがある場合)役立ちます。数千の単体テストを含む大規模なアプリケーションには、少し時間がかかります。これを回避するには、スコープを狭めてテストを即座に実行します。
短期とは、特定のタスクに集中している間のことです。リンターはこれを問題として報告する必要があります。完了したら、「唯一の」部分を削除して、すべてのテストを実行します。
変更が気づいていないコードの他の部分に影響を与えた可能性があるため、チェックインする前に必ずすべてのテストセットを実行してください。ただし、事前にテストの範囲を制限してもかまいません。新しいテストが成功するか失敗するかを確認するためだけに数千のテストが実行されるのを待つ必要はありません。
あなたが考えているのは、特定の機能を中心に構築された開発者が定義した一連のテストであるテストスイートの実行です。ユニットテストに関して厳密に言えば、クラスレベルでテストスイートを集中させることでこれを実現できます。すべてを分離してモックアウトすると、変更されたメソッドだけをテストできます。しかし、これはほとんど良い考えではありません。
あなたの意図は時間を節約することのようですが、10個のテストと100個のテストを実行するのに必ずしも10倍の時間がかかるわけではありません。すべてのテストを実行するには、必要なテストを実行するよりも長い時間がかかります。実際、テストに時間がかかる場合でも、おそらくいくつかのテストを使用する可能性があるため、すべてのテストを実行することをお勧めします。
ほとんどの場合、すべてのテストを実行しなかったために見逃したものを修正するよりも、すべてのテストを実行する方が時間を節約できます。実際、この理由から、ビルドプロセスにテストを追加しました。
Visual Studioにはライブユニットテストをオンにするオプションがあります。ライブユニットテストは、変更されたテストをインテリジェントに(VSの場合)検出し、それらのテストを再実行する傾向があります。それはあなたが望むものに近いかもしれませんが、コードをコミットする前にすべてのテストを実行する方法を強調することはできません。
.NETの場合、NCrunch(Visual Studio拡張を含む)があり、VS 2017 Enterprise Edition以降、Live Unit Testing機能があります。
Javaの場合、少なくともEclipseの拡張を含む)が存在します。