4

私はテストを始めたばかりで、最適なテスト戦略 (およびその適用) についてアドバイスが必要です。これが私の問題です:

ファイルを読み取り、その構造を自動的に抽出するプログラムがあります。この「インテリジェントな」抽出を行う方法をテストしたいと思います。最初に、いくつかのファイルを使用して、メソッドが正しい抽出を行っているかどうかを確認できます。次に、これらのファイルと (正しい) 抽出結果をテスト目的で使用したいと考えています。抽出結果は検証済みなので、さらなるテストに使用する必要があります (使用する必要があります)。

したがって、次のようなものがあります。「この特定のファイル」に対して、「この結果」を期待します。

問題点:

  1. テスト用の入力ファイルを簡単に取得できます。それらを特定のディレクトリに保存します。結果はどうですか?これらは、ファイル構造を格納するオブジェクトの内容に影響します。この場合、このオブジェクトもファイルに保存する必要があるかもしれません。シリアライゼーションでは、オブジェクトの構造が変更されると、以前に保存されたオブジェクトを再利用するのが難しくなるのではないかと心配しています。

  2. 結果が増えると、何百ものファイルと結果が得られる可能性があり、テストには多くの時間がかかります。テスト時間は大きな問題にはならないと思います。

メソッドで使用される「抽出アルゴリズム」は頻繁に変更されるため、テストが必要です。完璧な抽出アルゴリズムを実現するために、すべての可能性に対処することはできません。したがって、私の解決策は、1ダースのファイルで機能する初期アルゴリズムを構築し、特定のファイルのアルゴリズムに失敗を見つけるたびに、そのファイルの問題を解決するためにアルゴリズムを変更することです. 以前のファイルと結果が引き続き有効であるためには、この変更をテストする必要があります。

テスト戦略に関する提案はありますか?

4

3 に答える 3

1

テストの場合、入力テストデータを注入できる場所と、動作または出力を観察できる場所が必要です。

入力側:入力テストデータを挿入する可能性はファイルだけですか?はいの場合、アプリケーションにはテスト可能な優れた設計がありません。ファイルを使用したテストは保守が困難です。出力側:アプリケーションは、動作や出力を観察する可能性を提供していないようです。これは、テストできない設計を示しています。

出力の動作を観察する方法を見つけたとしても、すべての抽出アルゴリズムに対してエンドツーエンドのテストしかありません。このようなエンドツーエンドのテストは脆弱であり、メンテナンスの悪夢です。原因は、テスト可能な設計が適切でないことです。

優れたテスト可能な設計がなければ、優れたテスト戦略を実装することはできません。アプリケーションのデザインを変更する必要があります。一方、テストを実施せずに設計を変更したくないと主張する場合もあります。鶏が先か卵が先かという問題のようです。

そのような状況から抜け出す方法は?テスト戦略とリファクタリング戦略の組み合わせが役立つ場合があります。大まかに言えば、これは次のように機能する可能性があります。

  1. いくつかの代表的なエンドツーエンドテストを作成します。したがって、シリアル化のトリックも使用してください。これは、リファクタリングを開始する前に、プログラムが同じように機能することを確認するためだけのものです。それらは移行テストとして機能します。

  2. プログラムをリファクタリングします。注入して観察する場所を与えます。そのような場所は継ぎ目として知られています。

  3. その結果、テスト可能なチャンクが作成され、テストハーネスに入れることができます 。

  4. 単体テストが実施されるまで、リファクタリングして新しいシームをコードに追加し、小さなチャンクをテストします。理想的には、すべてのアルゴリズムを、すべてユニットテストされたクラスのファミリーにカプセル化する必要があります。

大変な仕事のように聞こえますか?いいえ、実際には思ったよりも難しいです。アプリケーションをテスト可能な設計にリファクタリングするには、多くの経験が必要です。幸いなことに、これについて本を書いた人がいます:MichaelFeatherの「LegacyCodeで効果的に作業する」

本当に、既存のアプリケーションに優れたテスト戦略を実装したい場合は、その本を読んでください。次回、もっとうまくできることを知りたい場合は、その本を読んでください。単体テストがテスト不可能な設計を回避するための鍵になる可能性があると思われる場合は、今すぐ単体テストについて学び始めてください。インターネットや単体テストに関する本にはたくさんのリソースがあります。

于 2013-01-19T18:50:44.250 に答える
0

私が問題を理解した場合は、後の検査または追加のテストのためにテストの結果を保持する必要があります。多くの場合、テスト コードの作成に多くの時間を費やすのは気が進まないものですが、この場合、すぐに利用できる代替手段はありません。

私のアドバイスは、アルゴリズム、永続化レイヤー (シリアライゼーション/デシリアライゼーション)、その製品、検証コードなど、関連する部分を可能な限り分離することです。

後のアルゴリズムの実装が同じインターフェースを共有できる可能性もあります。

interface IMyAlgorithm {
  AbstractOutput DoSomething (InputData);
}

class ConcreteOutput : AbstractOutput {
  // Output for version XXX of your algorithm
}

class XXXAlgorithm {
  ConcreteOutput DoSomething (InputData inputData)
    // Version XXX of you alogorithm
  }
}

interface IPersistenceManager {
  Serialize(AbstractOutput output, string filename);
  AbstractOutput Deserialize(string filename)
}

class XXXPersistenceManager : IPersistenceManager {
  // Handle persistence for XXX hierarchy
}

class XXXTestFixture {
  void BuildObjectWithXXXAlgorithm() {
    IMyAlgorithm XXX = new XXXAlgorithm();
    // run XXX here
    AbstractOutput objXXX = XXX.DoSomething(new InputData());
    IPersistenceManager pmXXX = new XXXPersistenceManager();
    pmXXX.Serialize(objXXX);
  }

  void VerifyThatXXXWorkAsExpected() {
    IPersistenceManager pmXXX = new XXXPersistenceManager();
    AbstractOutput objXXX = pmXXX.Deserialize(path);
    // check object here
  }
}

したがって、YYY などの新しいアルゴリズムを作成する必要がある場合は、対応する階層を作成します。詳細はわかりませんが、これは単なる疑似コードのドラフトであり、アプリケーション コンポーネントを疎結合することに重点を置くためだけにここに配置されています。

于 2013-01-19T14:21:07.197 に答える
0

承認テストを使用して、特定の入力ファイルが常にメモリ オブジェクト グラフで同じものを生成することを確認できます。

これを行うには、in-memory-object-graph を文字列表現に変換するコードが必要です (つまり、ToString() を上書きするか、xml-serializer を持つ)。

approvaltests は、生成された文字列が常に同じであることを確認します。

文字列表現が変更された場合、diff-viewer が表示され、変更が正常かどうかを確認するよう求められます。変更に問題がなければ、この結果を後の検証に使用します。

于 2013-01-19T15:41:24.713 に答える