Search code examples
c#nunit-3.0

How can I run nunit test with parameterized Repeat attribute


How can I tell NUnit to repeat tests in a fixture "n" times, when "n" is a variable in the test class that is set using TestFixtureSource instantiation of the base test class?

Actually I want to run my test suite two times:

  • Once each test should not repeat i.e. [Repeat(1)]
  • In another run, all of them must be repeated by the amount that I say! (You should know that, this time I do something in the constructor, and then I want to run same tests multiple times)

I don't want to copy the test suite two times!! I want NUnit to run it automatically!!!


Solution

  • From the comments it seems you want to test for external dependencies - e.g. the network-state, an external database or whatever. So in fact you have an integration-test.

    How you setup the dependencies for your tests is completely up to you, however I'd argue to do as much as possible within your code so your tests stay deterministic. What's the point of a green test, when you need to examine the exact result based on some other system - e.g. reading your log-files if really everything went well? Furthermore having everything in a single code-base enables for version-control and you easily see every change to your tests as well as to your entire system.

    As test-code is also just code, you can of course refactor it in order to reduce code-duplications for similar environments. So you may have two test-methods with nearly identical code, that only differ in a database-connection for instance. You don't need to run the first test, change your systems state, run the second test Instead you can embed the entire state-change directly in your code. See this short example:

    [Test]
    public void Test1() 
    {
        // code for setting up your systems new state
        var target = new MyClass();
        target.DoSomething();
        Assert.Pass();
    }
    
    
    [Test]
    public void Test2() 
    {
        // code for setting up your systems new state
        var target = new MyClass();
        target.DoSomething();
        Assert.Pass();
    }
    

    You can now refactor that so your two tests do the exact same things:

    [Test]
    public void Test2() 
    {
        // code for setting up your systems new state
        Test();
    }
    
    [Test]
    public void Test2() 
    {
        // code for setting up your systems new state
        Test();
    }
    
    private void Test() 
    {
        var target = new MyClass();
        target.DoSomething();
        Assert.Pass();
    }
    

    An alternative that enables you to run the exact same test again and again is by simply provide a dynamic number of testcases via the TestcaseSource-attribute:

    [TestCaseSource(nameof(GetTestCases))]
    public void Test() 
    {
        // code for setting up your systems new state
        Test();
    }
    
    public static IEnumerable<TestCaseData> GetTestCases() => Enumerable.Repeat(new TestCaseData(), numberOfRepitions);
    

    However that will run the tests one after the other, so you won't have time to change your systems state between two tests.