简体   繁体   中英

NUnit TestFixture and TestCase

I have to write some integration tests with NUnit that should test HTTP endpoints. This means that URL should be shared across all test methods.

[TestFixture("http://my.endpoint.com")]
public class TestSuiteOne
{
   [TestCase(10, 20, Expected = 30)]
   [TestCase(20, 30, Expected = 50)]
   public int TestA(int a, int b, HttpResponseMessage sut)
   {
        // AAA.
   }

   [TestCase("XXX", "YYY", Expected = "ABC")]
   public int TestA(string a, string b, HttpResponseMessage sut)
   {
        // AAA.
   }
}

To get SUT value on each test run that comes from test suite attribute I know two options:

Option A (read SUT from class property)


public abstract class TestSuiteBase
{
    protected(string endpoint)
    {
        Sut = endpoint;
    }

    protected HttpResponseMessage Sut { get; }
}

[TestFixture("http://my.endpoint.com")]
public class TestSuiteOne : TestSuiteBase
{
   public TestSuiteOne(string endpoint) : base(endpoint)
   {
   }

   [TestCase(10, 20, Expected = 30)]
   [TestCase(20, 30, Expected = 50)]
   public int TestA(int a, int b)
   {
        // act (read content/response code/headers/etc); Making a call I do not consider as act.
        var actual = Sut.DoSomething();

        // assert
   }

   [TestCase("XXX", "YYY", Expected = "ABC")]
   public int TestA(string a, string b)
   {
        // act (read content/response code/headers/etc); Making a call I do not consider as act.
        var actual = Sut.DoSomething();

        // assert
   }
}

Option B (intercept test method call)

public class MyTestCase: TestCaseAttribute
{
    public MyTestCase(params object[] args) : base(Resize(args))
    {
    }

    // I do resize before method call because VS Test Adapters discover tests to show a list in the test explorer
    private static object[] Resize(params object[] args)
    {
        Array.Resize(ref args, args.Length + 1);
        args[args.Length - 1] = "{response}";

        return args;
    }
}

public abstract class TestSuiteBase
{
   [SetUp]
   public void OnBeforeTestRun()
   {
       var ctx = TestContext.CurrentContext;

       var args = ctx.Test.Arguments;

       // Making a call I do not consider as act.
       args[args.Length - 1] = MakeCallAndGetHttpResponseMessage(args);
   }
}

[TestFixture("http://my.endpoint.com")]
public class TestSuiteOne : TestSuiteBase
{
   [MyTestCase(10, 20, Expected = 30)]
   [MyTestCase(20, 30, Expected = 50)]
   public int TestA(int a, int b, HttpResponseMessage sut)
   {
        // act (read content/response code/headers/etc); Making a call I do not consider as act.
        var actual = sut.DoSomething();

        // assert
   }

   [MyTestCase("XXX", "YYY", Expected = "ABC")]
   public int TestA(string a, string b, HttpResponseMessage sut)
   {
        // AAA.
   }
}

Is there any more convenient way how to combine value that comes from TestFixture with TestCase?

Since you placed the endpoint string on the TestFixtureAttribute , I will assume

  1. That you want to share it with all the test cases in the fixture.
  2. That you do not want to share it with any other fixtures.

The only thing missing in your example is a constructor that will accept the argument you are providing. Just add something like...

public TestSuiteOne(string url)
{
     Sut = endpoint;
}

So long as you make Sut a readonly property or field, none of your testcases will be able to change it, whether they are run sequentially or in parallel.

Both the options you provide seem overly complex to me, at least insofar as you have explained the problem. The first one is closest to this answer.

Of course, it's entirely possible that you might do other things with the web site, which would cause parallel (or even sequential) tests to interfere with one another. Don't do that. :-) Seriously, sharing a driver is entirely different from sharing a string, but that's a different question.

IMO, by the way, you and your team should get used to one test framework or another. The lifecycle issue you mention is not the only subtle difference between NUnit and xUnit!

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