简体   繁体   中英

How to debug theories in xunit tests

I have big amount of similar tests which I implement as a theory using MemberData attribute. How can I navigate to each fallen test case and debug it?

Here an example:

    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);
    }

Well, you can set conditional breakpoint in TestMethod1 and try to find fallen test case. But in many cases it is not so comfortable.

One trick can be helpful here:

    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);
        });
    }

Idea is to put target logic and assertions into callback and call it through a special similar lambdas which are injected in each test case. Every of that lambdas will be passed as argument and called in test method, so it will be present in stack trace. And when some test case will fall, you can easily navigate to it through StackTrace by clicking on corresponding line (in this example it will looks like ' at UnitTestProject1.ExampleTests2.<>c.b__4_0(Action l) ')

Also, you can set breakpoint inside lambda of that test case, which you want to debug and see what is happen with data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM