如何在xunit测试中调试理论

时间:2016-05-29 22:25:49

标签: c# unit-testing xunit

我有大量类似的测试,我使用MemberData属性作为理论实现。如何导航到每个堕落的测试用例并进行调试?

这是一个例子:

    public const int A = 2;
    public const int B = 3;
    public const int C = 2;

    public static IEnumerable<object[]> GetTestCases
    {
        get
        {
            // 1st test case
            yield return new object[]
            {
                A, B, 4
            };

            // 2nd test case
            yield return new object[]
            {
                A, C, 4
            };
        }
    }

    [Theory]
    [MemberData("GetTestCases")]
    public void TestMethod1(int operand1, int operand2, int expected)
    {
        // Q: How can I debug only test case, which is failed?
        //...and break execution before exception will be raised
        var actual = operand1 + operand2;
        Assert.Equal(actual, expected);
    }

1 个答案:

答案 0 :(得分:0)

好吧,你可以在TestMethod1中设置条件断点并尝试找到堕落的测试用例。但在许多情况下,它并不那么舒服。

这里有一个技巧有用:

    public const int A = 2;
    public const int B = 3;
    public const int C = 2;

    public static IEnumerable<object[]> GetTestCases
    {
        get
        {
            // 1st test case

            // This line will be in stack trace if this test will failed
            // So you can navigate from Test Explorer directly from StackTrace.
            // Also, you can debug only this test case, by setting a break point in lambda body - 'l()'
            Action<Action> runLambda = l => l();

            yield return new object[]
            {
                A, B, 4,
                runLambda
            };


            // 2nd test case

            runLambda = l => l();

            yield return new object[]
            {
                A, C, 4,
                runLambda
            };

            // ...other 100500 test cases...
        }
    }

    [Theory]
    [MemberData("GetTestCases")]
    public void TestMethod1(int operand1, int operand2, int expected, Action<Action> runLambda)
    {
        // pass whole assertions in a callback 
        runLambda(() =>
        {
            var actual = operand1 + operand2;
            Assert.Equal(actual, expected);
        });
    }

想法是将目标逻辑和断言放入回调中,并通过在每个测试用例中注入的特殊类似lambda来调用它。每个lambda都将作为参数传递并在测试方法中调用,因此它将出现在堆栈跟踪中。当一些测试用例崩溃时,你可以通过点击相应的行轻松地通过StackTrace导航到它(在这个例子中,它看起来像' at UnitTestProject1.ExampleTests2。&lt;&gt; c.b__4_0(Action l)< / em>')

此外,您可以在该测试用例的lambda中设置断点,您要调试该测试用例并查看数据会发生什么。