我正在尝试更严格地遵循“每个单元测试一个断言”的做法。这并不总是可能的,但我确实发现它对于查明错误很有用。
例如我可能有这样的东西:
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”失败(或使用普通断言)时抛出异常,那么我相信该组的测试根本不会运行。您还可以使用静态类初始化 ( http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.classinitializeattribute.aspx )。但是,所有测试仍将被标记为失败。
关于c# - 是否有一个属性可以避免 MSTest 中的级联单元测试失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18251244/