简体   繁体   中英

How to force a test run last in visual studio using NUnit

So in my test suite, I have an abstract base class that my integration tests inherit from. Each derivation of this base class has their own set of tests. The assertions that the child classes make are run through protected methods on the base class. During those assertions, the base class logs which values in a dictionary have been tested. After the child classes have run all their tests, I want the base class to run a test that verifies all the correct things were tested.

A few disclaimers:

  1. Yes, I know this is an ordered test, and that those are frowned upon. However, this is something I want to do anyway.
  2. I know this is a test that tests my test suite, in a sense. While this is often frowned upon, I find it useful. If you want your tests to genuinely be your documentation, it is good to have some rudimentary tests that verify some basic things about your documentation - that it's complete, for example. (In most projects, this would probably be overkill and not worth it. In this particular project, however, it is both a personal project and an experiment in working with 100% code coverage.)

For now, I have marked the summary test with both [Test] and [TestFixtureTearDown] , which does make the test run at the end. However, it also means that when the test fails, the test suite gets angry because a tear down failed. What I want in an ideal world is something like [RunLast]. Any ideas on how one might be able to accomplish this?

Example of the code currently:

[TestFixture]
public abstract class AttributesTests : IntegrationTests
{
    [Inject]
    public IAttributesMapper AttributesMapper { get; set; }

    protected abstract String tableName { get; }

    private Dictionary<String, IEnumerable<String>> table;
    private List<String> testedNames;

    [TestFixtureSetUp]
    public void FixtureSetup()
    {
        testedNames = new List<String>();
    }

    [SetUp]
    public void Setup()
    {
        table = AttributesMapper.Map(tableName);
    }

    [Test, TestFixtureTearDown]
    public void AllNamesTested()
    {
        var missingNames = table.Keys.Except(testedNames);
        Assert.That(missingNames, Is.Empty, tableName);
    }

    [Test, TestFixtureTearDown]
    public void NoNamesTestedNultipleTimes()
    {
        var duplicateNames = testedNames.Where(n => testedNames.Count(cn => cn == n) > 1).Distinct();
        Assert.That(duplicateNames, Is.Empty, tableName);
    }

    protected void AssertAttributes(String name, IEnumerable<String> attributes)
    {
        testedNames.Add(name);

        Assert.That(table.Keys, Contains.Item(name), tableName);

        foreach (var attribute in attributes)
        {
            Assert.That(table[name], Contains.Item(attribute));

            var actualAttributeCount = table[name].Count(a => a == attribute);
            var expectedAttributeCount = attributes.Count(a => a == attribute);
            Assert.That(actualAttributeCount, Is.EqualTo(expectedAttributeCount));
        }

        var extraAttributes = table[name].Except(attributes);
        Assert.That(extraAttributes, Is.Empty);
    }
}

This works for me:

namespace ZZZ
public class ZZZZZ {
  [Test]
  public void ZZZZLastTest() {
    // Whatever . . . 
  }
}

There is no explicit [LastTest] -like attribute that I am aware off but I believe you can go with [Suite] instead.

I know this JUnit approach to suites will execute your test classes in lineair order as they are defined (although there is no guarantee to the order in which your tests inside one class are executed).

@RunWith(Suite.class)
@SuiteClasses({ CalculatorTestAdd.class, CalculatorTestSubtract.class })
public class AllTests {

}

Here CalculatorTestSubtract will be executed last. Keeping this in mind, I would say that you should create a suite which has your summary test at the end.

Looking at NUnit documentation , I see that something should be equally possible:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  private class AllTests
  {
    [Suite]
    public static IEnumerable Suite
    {
      get
      {
        ArrayList suite = new ArrayList();
        suite.Add(new OneTestCase());
        suite.Add(new AssemblyTests());
        suite.Add(new NoNamespaceTestFixture());
        return suite;
      }
    }
  }
}

You'll have to do some tests to see if they get executed linearly because an ArrayList is not guaranteed to be sorted.

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