3

コードがテスト用にセットアップされていない限り、コードをテストできないことは一般的に認められていますか?

仮定のコード:

public void QueueOrder(SalesOrder order)
{
   if (order.Date < DateTime.Now-20)
      throw new Exception("Order is too old to be processed");
   ...  
}

次のようにリファクタリングすることを検討する人もいます。

protected DateTime MinOrderAge;
{
   return DateTime.Now-20;
}

public void QueueOrder(SalesOrder order)
{
   if (order.Date < MinOrderAge)
      throw new Exception("Order is too old to be processed");
   ...
}

注:さらに複雑なソリューションを考え出すこともできます。IClockインターフェイスとファクトリが含まれます。それは私の質問には影響しません。

上記のコードを変更する際の問題は、コードが変更されたことです。顧客が変更を要求することなく、コードが変更された。また、変更にはミーティングと電話会議が必要です。そのため、何もテストしない方が簡単な時点にいます。

変更したくない/できない場合: テストを実行できなくなりますか?

注:上記の疑似コードは C# のように見えるかもしれませんが、それは単に読みやすくするためです。質問は言語に依存しません。

注:架空のコード スニペット、問題、リファクタリングの必要性、およびリファクタリングは架空のものです。もしあなたが私のものに不満を持っているなら、あなた自身の架空のコードサンプルを挿入することができます.

注:上記の仮想コードは仮想です。生きているか死んでいるかにかかわらず、コードとの関係はまったくの偶然です。

注:コードは架空のものですが、答えはありません。質問は主観的なものではありません。答えがあると私は信じています。


更新:もちろん、ここでの問題は、上記の例の変更によって何も壊れていないことを保証できないことです。確かに、コードの一部を別のメソッドにリファクタリングしましたが、コードは論理的に同一です。

しかし、新しい保護されたメソッドを追加してもオブジェクトの仮想メソッド テーブルがオフセットされなかったことを保証することはできません。このクラスが DLL 内にある場合は、アクセス違反が発生したことになります。

4

7 に答える 7

4

答えはイエスです。テスト可能にするために、一部のコードを変更する必要があります。

しかし、変更せずにテストできるコードがたくさんある可能性があります。最初にその部分のテストを書くことに集中し、次に、他の顧客の要件によってテスト可能な方法でリファクタリングする機会が得られたら、残りのテストを書きます。

于 2010-10-27T13:37:43.297 に答える
1

コードは最初からテスト可能に書くことができます。最初からテスト容易性を念頭に置いて作成されていない場合でも、テストは可能ですが、問題が発生する可能性があります。

架空のコードで、かなり過去の日付で SalesOrder を作成して元のコードをテストするか、DateTime.Now をモック アウトすることができます。あなたが示したようにコードをリファクタリングすることは、テストには適していますが、絶対に必要というわけではありません。

于 2010-10-27T13:36:50.747 に答える
1

モック オブジェクト フレームワークを使用して、元の例の単体テストを行うことができます。この場合、SalesOrder オブジェクトを数回モックし、毎回異なる Date 値を構成してテストします。これにより、出荷されたコードを変更する必要がなくなり、問題のアルゴリズムを検証して、注文日がそれほど遠くないことを確認できます。

対処している依存関係と、自由に使える言語機能を考慮して何が可能かを全体的に把握するには、レガシー コードで効果的に作業することをお勧めします。

于 2010-10-27T17:01:41.383 に答える
1

コードがテスト用に設計されていない場合、テストはより困難になります。あなたの例では、おそらく簡単な作業ではない DateTime.Now Method をオーバーライドする必要があります。

コードにテストを追加してもほとんど価値がないと思うか、既存のコードの変更が許可されていない場合は、それを行うべきではありません。

ただし、TDD を信頼している場合は、テストを使用して新しいコードを作成する必要があります。

于 2010-10-27T13:40:55.037 に答える
0

この種のコードの問題は常に、多くの静的クラス、フレームワークの種類などを作成し、それらに依存していることです...

これらすべてのオブジェクトに偽物を「注入」するための非常に優れたソリューションは、Typemock Isolator (商用ですが、1 セントの価値があります) です。そうです、確かに、テスト容易性を考慮せずに書かれたレガシー コードをテストできます。私は Typemock を使った大きなプロジェクトでそれを行い、非常に良い結果を得ました。

Typemock の代わりに、基本的に同じことを行う無料の MS Moles フレームワークを使用することもできます。それは、非常に非直感的な API を備えており、学習と使用がはるかに難しいということだけです。

HTH。
トーマス

于 2010-10-27T13:43:16.723 に答える
0

これは、一部の動的言語では簡単に実現できます。たとえば、SUT (System Under Test) がそれを暗黙の依存関係として使用している場合でも、import/using ステートメント内にフックして、実際の依存関係をスタブ依存関係に置き換えることができます。または、それらのシンボル (クラス、メソッド、関数など) を再定義できます。これが進むべき道だと言っているのではありません。物事はリファクタリングする必要がありますが、いくつかの特性テストを作成する方が簡単です。

于 2010-10-27T13:38:16.290 に答える
0

Mockito + Mockito の PowerMock。

コードを大幅に変更することなく、ほぼすべてをテストできます。ただし、モックを注入するにはいくつかのセッターが必要になります。

于 2010-10-29T15:54:40.787 に答える