【问题标题】:Is there an attribute to avoid cascade unit test failures in MSTest?是否有一个属性可以避免 MSTest 中的级联单元测试失败?
【发布时间】:2013-08-15 19:16:27
【问题描述】:

我正在尝试更密切地遵循“每个单元测试一个断言”的做法。这并不总是可能的,但我确实发现它对于查明错误很有用。

例如我可能有类似的东西:

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,那么我会得到一个单元测试失败,以及一堆更不确定的测试。当我修复一个失败的测试时,其他一切都通过了。

这有两个地方会下降。一是我现在在几乎所有单元测试的开始都有重复代码。

第二个问题是当我想设置和检查一个更复杂的对象时(在这个虚拟示例中 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]
}

单元测试现在非常简单 - 没有重复,并且现在可以自动保持测试与其“先决条件”同步。

有这样的吗?或者我可以使用完全不同的功能来获得相同的效果?

我知道将属性中的测试方法引用到另一个测试方法几乎肯定存在问题 - 您可能必须使用硬编码到方法名称的字符串(如果方法名称会发生​​什么情况更改,或该方法不存在)。我确信循环引用也存在潜在问题。但是,尽管存在所有这些问题,但一定有人已经解决了这个问题。谁能给我指点一下?

【问题讨论】:

  • 恕我直言,您的单元测试逻辑太多。它们应该简明扼要,不包含太多逻辑。他们也不应该依赖其他测试。我认为你需要重新考虑你的方法。
  • 当你说“重新考虑你的方法”时,你的意思是重新考虑单元测试的编写方式(我不应该一直检查 toTest 是否为空),或者重新考虑下类的依赖关系test(toTest 不应该有一个必须设置的数组)?

标签: c# unit-testing attributes


【解决方案1】:

不鼓励测试之间的依赖关系。您的问题的可能解决方案:如果您在测试初始化​​方法中创建“toTest”失败(或使用普通 Assert)时抛出异常,那么我相信该组的测试根本不会运行。您还可以使用静态类初始化 (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.classinitializeattribute.aspx)。但是,所有测试仍将被标记为失败。

【讨论】:

  • 如果我在 TestInitialize 方法中抛出异常,那么所有单元测试都会失败。如果创建不起作用,我的目标是让一个单元测试失败,以便很容易查明问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多