3

ソフトウェアテストに関するガイダンスが必要です。

私は物事を複雑にしすぎていますが、私は自分が間違っていること、または物事を行う別の方法を見るにはあまりにも固執しています。

同じプライベートメソッドを使用しているパブリックメソッドがいくつかあります。

プライベートメソッド自体:

  • その特定の役割のために多くのシナリオを処理する必要があります
  • 同じインスタンス内のフィールド/プロパティ/メソッドと緊密に連携します

プライベートメソッドはすべてのシナリオをカバーするために5つのテストが必要であり、6つのパブリックメソッドによって使用されるとします。

質問

  • 次に、少なくとも5x6テストが必要ですか?

  • パブリックメソッドごとにプライベートメソッドのテストを再利用するにはどうすればよいですか?

  • 繰り返されるテストのリファクタリングに関する例/記事はありますか?

始めるとき()

- if_file_exists_load_entries           ()
- if_file_missing_load_last             ()
- if_no_files_create_new_entries        ()
- if_exception_clear_entries_and_log    ()
- loaded_entries_init_called            ()
- Other tests

OnUserLoadCustom()

- if_file_exists_load_entries           _AND_STORE_AS_LAST()
- if_file_missing_load_last             _AND_STORE_AS_LAST_AND_WARNING_MESSAGE()
- if_no_files_create_new_entries        _AND_WARNING_MESSAGE()
- if_exception_clear_entries_and_log    _AND_ERROR_MESSAGE()
- loaded_entries_init_called            _AND_SUCCESS_MESSAGE()
- Other tests

OnRecover()

- if_file_exists_load_entries           _AND_INFO_MESSAGE()
- if_file_missing_load_last             _AND_INFO_MESSAGE()
- if_no_files_create_new_entries        _AND_INFO_MESSAGE()
- if_exception_clear_entries_and_log    _AND_ERROR_MESSAGE_AND_SHUTDOWN()
- loaded_entries_init_called            _AND_SUCCESS_MESSAGE()
- Other tests

Strategyパターンを使用してプライベートメソッドをカプセル化することを検討しているので、それ(およびパブリックメソッド)を分離してテストできます。

ただし、次の理由で使用するのが適切ではありません。

  • 実行時に互換性のある動作をするつもりはありません
  • テストを簡単にするためにパターンを使用するのは間違っているようです

アップデート#1

私の質問は、プライベートメソッドの動作についてパブリックインターフェイスをテストすることに関するものです。しかし、私は多くの重複したテスト方法になってしまいます(上記の私の例を参照してください)。

戦略パターンでは、必要なのは次のとおりです。

  • 戦略のすべてのパスをテストします(基本的に、プライベートメソッドをテストします)
  • すべてのパブリックメソッドがストラテジーを呼び出すことを確認します(ここでモックオブジェクトを簡単に使用でき、呼び出されたことを確認できます)

しかし、私が述べたように、テストを容易にするためだけにパターンを導入するべきではないと思います。本当に必要な場合を除いて、私はこのアプローチを延期しています。


アップデート#2

重複を減らす最初の試み:

  • 独自のクラスにグループ化されたプライベートメソッドテスト(Behaviour1Test)

    • GetTestCases()は、この動作に関連するテストケースのリストを返します
  • このテストを必要とするすべてのパブリックメソッドは、公開するインターフェイスを実装します

    • 整える()
    • 活動()
    • 主張する()

例えば:

// Public method tests
[TestFixture]
public class PublicMethodTests: IBehaviour1Test
{
    // Behaviour 1
    Behaviour1Test _behaviour1;
    IEnumerable<TestCaseData> Behaviour1TestCases{ get { return _behaviour1.GetTestCases(); } }
    [Test]
    [TestCaseSource("Behaviour1TestCases")]
    public void RunBehaviour1Test(Action<IBehaviour1Test> runTestCase)
    {
        runTestCase(this);
    }

    // ==============================
    // Behaviour 1 Arrange/act/assert
    void IBehaviour1Test.Arrange(){}
    void IBehaviour1Test.Assert(object result){}
    object IBehaviour1Test.Act()
    {
        return _model.PublicMethod();        
    }

    // Other tests
}

// Implement this in order to run Behaviour1 test cases
interface IBehaviour1Test
{
    void Arrange(); 
    object Act();
    void Assert(object retValue);
}

// Collection of tests for behaviour 1
public class Behaviour1Test
{
    // Generate test cases
    IEnumerable<TestCaseData>() GetTestCases()
    {
        yield return new TestCaseData((Action<IBehaviour1Test>)Test_1);
        yield return new TestCaseData((Action<IBehaviour1Test>)Test_2);
        yield return new TestCaseData((Action<IBehaviour1Test>)Test_3);
    }

    void Test_1(IBehaviour1Test impl)
    {
        // Arrange
        impl.Arrange(); // public method's arrange
        Test1Setup(); // Arrange for this test

        // Act
        var result = impl.Act();

        // Assert
        Test1Assert(result); // Assert for this test
        impl.Assert(result); // Assert on public method

    }

    void Test_2(IBehaviour1Test impl){}
    void Test_3(IBehaviour1Test impl){}
}

このように、プライベートメソッドの動作に新しいテストケースを追加する必要がある場合は、BehaviourTestに1回追加するだけで、それを含むすべてのパブリックメソッドテストが更新されます。

ここに画像の説明を入力してください

4

3 に答える 3

2

アプリケーションコードで行うのと同じ哲学をテストに適用する必要があります。共通の機能をヘルパーメソッドまたはクラスに抽出できる場合は、そうする必要があります。これにより、コードの重複が節約され、プライベートメソッドが変更された場合に後でリファクタリングするのに役立ちます。

一般化できるコードの一般的なセットアップ、分解、アサート、検証がたくさんあると思います。

于 2012-10-02T00:33:46.180 に答える
1

ある意味では、プライベートメソッドをテストしません。プライベートメソッドを使用するメソッドを徹底的にテストすると、すべてがチェックアウトされ、プライベートメソッドが「機能」します。

本当に安心したい場合は、リフレクションを使用してプライベートメソッドを実行できます。そうすれば、単独でテストできます。

テストのリファクタリングに関しては、もちろん、これらのそれぞれの機能を処理するためのセットアップとティアダウンのルーチンが必要です。テストではストラテジーパターンには入りません。複数のテストに必要な機能のチャンクを含む非テストメソッドをテストクラスに作成し、それらを適切に使用するだけです。たとえば、プライベートメソッドが5つのフィールドに影響を与える可能性があり、それらの5つのフィールドを複数回テストする必要がある場合、次のようなメソッドを作成します。

private void verifyField(expected1, extpected2, ....){
     equals(actual1, expected1, 'expected1 correct);
     ....
}

必要に応じて使用してください。

于 2012-09-28T12:11:27.210 に答える
0

プライベートメソッドをヘルパークラスに抽出する必要があります。次に、その機能を個別にテストし、他のテストでモックします。プライベートメソッド内の機能は、他のメソッドでテストしようとしているものとは何の関係もありません。入力を提供するだけです。ほとんどのプライベートメソッドは通常、解放されるのを待っている単なるヘルパーメソッドです。

于 2012-10-03T13:25:57.817 に答える