如何在首次失败时停止MsTest测试执行?
我们正在运行每晚构建,最后使用MsTest框架运行所有UnitTest.
We are running nightly builds which at the end run all of our UnitTest using the MsTest framework.
我们必须具有100%的通过率,因此,如果其中一项失败,就没有其他方面的用处.因此,我们希望在第一个失败的测试上停止执行.
We must have 100% pass rate, so if one fails there is no point running the others; hence we will like to stop the execution on the first failed test.
反正我们能做到吗?
您确定要放弃测试结果吗?
Are you really sure you want to throw away test results?
假设某人过得很糟糕,并在您的代码中引入了多个错误A,B和C.您可能只在星期一发现有关A的信息,因此您要进行修复,并且直到星期二才知道问题B,然后直到星期三才解决C问题.但是,由于您错过了半个星期的测试时间,因此星期一引入的错误直到被引入后的几天才会被发现,而且价格更高,而且修复所需的时间也更长.
Say somebody has a bad day and introduces multiple bugs A, B, and C into your code. You might only find out about A on Monday, so you fix that, and you don't know about issue B until Tuesday, and then you don't fix C until Wednesday. But since you were missing test coverage for half a week, bugs introduced Monday aren't discovered until days after they were introduced, and it's more expensive and takes longer to fix them.
如果在失败后继续运行测试并不会花费很多钱,那么这些信息对您有用吗?
If it doesn't cost you much to keep running the tests after a failure, isn't that information useful?
也就是说,在您的测试库中整理一个修补程序并不难.让测试失败的所有可能代码路径都设置一个静态变量StopAssert.Failed = true;
(可能是通过包装对Assert
的调用并捕获AssertFailedExceptions
来实现的.然后只需向每个测试类添加[TestInitialize()]
方法即可在失败后停止每个测试!>
That said, hacking together a fix in your test libraries wouldn't be that hard. Have all possible codepaths of test failure set a static variable StopAssert.Failed = true;
(probably by wrapping calls to Assert
and catching AssertFailedExceptions
. Then just add [TestInitialize()]
methods to each test class to stop each test after a failure!
public class StopAssert
{
public static bool Failed { get; private set; }
public static void AreEqual<T>(T expected, T actual)
{
try
{
Assert.AreEqual(expected, actual);
}
catch
{
Failed = true;
throw;
}
}
// ...skipping lots of methods. I don't think inheritance can make this easy, but reflection might?
public static void IsFalse(bool condition)
{
try
{
Assert.IsFalse(condition);
}
catch
{
Failed = true;
throw;
}
}
}
[TestClass]
public class UnitTest1
{
[TestInitialize()]
public void Initialize()
{
StopAssert.IsFalse(StopAssert.Failed);
}
[TestMethod]
public void TestMethodPasses()
{
StopAssert.AreEqual(2, 1 + 1);
}
[TestMethod]
public void TestMethodFails()
{
StopAssert.AreEqual(0, 1 + 1);
}
[TestMethod]
public void TestMethodPasses2()
{
StopAssert.AreEqual(2, 1 + 1);
}
}
[TestClass]
public class UnitTest2
{
[TestInitialize()]
public void Initialize()
{
StopAssert.IsFalse(StopAssert.Failed);
}
[TestMethod]
public void TestMethodPasses()
{
StopAssert.AreEqual(2, 1 + 1);
}
[TestMethod]
public void TestMethodFails()
{
StopAssert.AreEqual(0, 1 + 1);
}
[TestMethod]
public void TestMethodPasses2()
{
StopAssert.AreEqual(2, 1 + 1);
}
}