13

我们正在运行每晚构建,最终使用 MsTest 框架运行我们所有的 UnitTest。

我们必须有 100% 的通过率,所以如果一个失败了,那么运行另一个没有意义;因此,我们希望在第一次失败的测试中停止执行。

无论如何我们可以做到吗?

4

1 回答 1

0

Are you really sure you want to throw away test results?

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?


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);
    }
}
于 2013-12-31T21:33:12.533 回答