2013-08-15 15 views
5

私は、「単体テスト1つのアサーション」の実践をより詳細に追及しようとしています。常に可能なわけではありませんが、エラーの特定に役立ちます。 toTestの作成が失敗した場合、その後、他のユニットテストのすべてがあまりにも失敗する問題があるMSTestでカスケードユニットテストの失敗を回避する属性はありますか?

var toTest; 

[TestInitialize] 
Init() { 
    toTest = // Create toTest 
} 

[TestMethod] 
TestIsCreated() { 
    Assert.IsNotNull(toTest); 
} 

[TestMethod] 
TestIsProperty1Setup() { 
    Assert.IsNotNull(toTest.Property1); 
    // Maybe some more tests on Property1 
} 

// More tests for other properties... 

例えば私のようなものがあるかもしれません。したがって、次のようなチェックを追加できます。

... 

[TestMethod] 
TestIsProperty1Setup() { 
    if (toTest == null) Assert.Inconclusive() 
    Assert.IsNotNull(toTest.Property1); 
    // Maybe some more tests on Property1 
} 

... 

これは、カスケードの失敗を防止し、正確な問題を指摘します。 // Create toTest行がnullを返した場合、私はちょうど1つの単体テストが失敗し、より束縛されないテストが得られます。私が失敗したテストを修正すると、それ以外はすべてパスします。

この場所が2つあります。 1つは、ほぼすべての単体テストの開始時にコードを繰り返すことです。私がセットアップしたい、より複雑なオブジェクトをチェックするとき

第二の問題は、(このダミーの例ではtoTestもアレイを有する)である。

[TestMethod] 
TestArrayIsNotNull() { 
    if (toTest == null) Assert.Inconclusive(); 
    Assert.IsNotNull(toTest.Array); 
} 

[TestMethod] 
TestArrayIsInitilizedWithOneElement() { 
    if (toTest == null) Assert.Inconclusive(); 
    if (toTest.Array == null) Assert.Inconclusive(); 
    Assert.AreEqual(1, toTest.Array.Count()) 
} 

[TestMethod] 
TestArrayIsInitilizedWithCorrectElement() { 
    if (toTest == null) Assert.Inconclusive(); 
    if (toTest.Array == null) Assert.Inconclusive(); 
    if (toTest.Array.Count() != 1) Assert.Inconclusive(); 
    // Assert something about toTest.Array[0] 
} 

今そこに個々のテストのためのより多くの重複したコードであり、もっと重要なのは、異なるテスト間でアサーションを同期させなければならないことです。つまり、小さな変更が多くの​​ユニットテストに波及する可能性があります。

理想的には、各テストの先頭に位置する属性を持ち、「前提条件」テストが合格した場合にのみテストを実行したいと考えています。そこには重複がなく、彼らの「前提条件」今自動的に行われますと同期のテストを保つ - ユニットテストは現在、非常に簡単です

[TestMethod] 
[OnlyRunIfOtherTestPasses(TestIsCreated())] 
TestArrayIsNotNull() { 
    Assert.IsNotNull(toTest.Array); 
} 

[TestMethod] 
[OnlyRunIfOtherTestPasses(TestArrayIsNotNull())] 
TestArrayIsInitilizedWithOneElement() { 
    Assert.AreEqual(1, toTest.Array.Count()) 
} 

[TestMethod] 
[OnlyRunIfOtherTestPasses(TestArrayIsInitilizedWithOneElement())] 
TestArrayIsInitilizedWithCorrectElement() { 
    // Assert something about toTest.Array[0] 
} 

:それは次のようになります。

このような画像がありますか?それとも同じ効果を得るために使用できる全く異なる機能がありますか?

他のテストメソッドへの属性のテストメソッドの参照にはほとんど問題はないことに気付いています。おそらく、メソッド名にハードコードされた文字列を使用する必要があります(メソッド名前が変更されたり、メソッドが存在しません。循環参照にも潜在的な問題があると確信しています。しかし、これらの問題にもかかわらず、誰かがこの問題に取り組んできたに違いありません誰かが私にそれを指摘できますか?

+1

あなたのユニットテストでは論理が多すぎます。それらは簡潔であり、多くの論理を含んではいけません。彼らはまた、他のテストに依存すべきではありません。私はあなたのアプローチを再考する必要があると思います。 – Belogix

+0

「あなたのアプローチを再考する」と言ったら、単体テストの書き方を再考するか(toTestが常にnullであるかどうかを調べるべきではありません)、あるいはテスト中のクラスの依存関係を再考する必要がありますアレイを設定する必要があります)? – Jonny

+0

重複している:http://stackoverflow.com/questions/15871933/how-to-stop-mstest-tests-execution-on-first-failure – BartoszKP

答えて

0

テスト間の依存関係はお勧めできません。可能な解決策:テスト初期化メソッドで "toTest"の作成が失敗する(または通常のAssertを使用する)場合に例外をスローすると、そのグループのテストはまったく実行されません。静的クラス初期化(http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.classinitializeattribute.aspx)を使用することもできます。ただし、すべてのテストにはまだ失敗とマークされます。

+0

TestInitializeメソッドで例外をスローすると、すべての単体テストが失敗します。創造がうまくいかず、問題を正確に突き止めるのが非常に簡単であれば、私は正確に1つの単体テストを失敗させることを目指しています。 – Jonny

関連する問題