5

私は、「単体テストごとに 1 つのアサーション」という慣行をより厳密に守ろうとしています。常に可能であるとは限りませんが、エラーを特定するのに役立ちます。

たとえば、次のようなものがあります。

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...

問題は、toTest の作成が失敗した場合、他のすべての単体テストも失敗することです。したがって、次のようにチェックを追加できます。

...

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

...

これにより、カスケード障害が停止し、正確な問題が指摘されます。// Create toTest 行が null を返した場合、ユニット テストが 1 つだけ失敗し、さらに多くの不確定なテストが発生します。失敗したテストを 1 つ修正すると、他のすべてが成功します。

これが落ちる箇所が2ヶ所あります。1 つは、ほぼすべての単体テストの開始時にコードを繰り返すようになったことです。

2 番目の問題は、より複雑なオブジェクトをセットアップしてチェックする場合です (このダミーの例では、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]
}

現在、個々のテストごとに重複するコードが増えており、さらに重要なことに、アサートは異なるテスト間で同期を維持する必要があります。つまり、1 つの小さな変更が多くの​​単体テストに波及する可能性があります。

理想的には、各テストの一番上に配置され、「前提条件」のテストに合格した場合にのみテストを実行する属性が必要です。次のようになります。

[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]
}

単体テストは非常にシンプルになりました。重複はなく、テストを「前提条件」と同期させることは自動的に行われます。

このようなものはありますか?または、同じ効果を得るために使用できるまったく異なる機能はありますか?

属性内のテスト メソッドを別のテスト メソッドに参照することには、ほぼ確実に問題があることを認識しています。おそらく、メソッド名にハード コードされた文字列を使用する必要があります (したがって、メソッド名が変更された場合、またはメソッドは存在しません)。循環参照にも潜在的な問題があると確信しています。しかし、これらすべての問題にもかかわらず、誰かがこの問題に対処したに違いありません。誰でも私にそれを指摘できますか?

4

1 に答える 1