简体   繁体   English

如何使用NUnit在Visual Studio中强制最后一次运行测试

[英]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.) (在大多数项目中,这可能是过大的,并不值得。但是,在这个特定项目中,它既是个人项目,也是在100%代码覆盖率下进行的实验。)

For now, I have marked the summary test with both [Test] and [TestFixtureTearDown] , which does make the test run at the end. 现在,我已经用[Test][TestFixtureTearDown]标记了摘要测试,这确实使测试在最后运行。 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]. 在理想的世界中,我想要的是[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. 我不知道没有[LastTest]的显式属性,但我相信您可以改用[Suite]

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). 我知道这种JUnit套件方法将按照定义的lineair顺序执行测试类(尽管不能保证在一个类中执行测试的顺序)。

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

}

Here CalculatorTestSubtract will be executed last. 在这里, CalculatorTestSubtract将最后执行。 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: 查看NUnit文档 ,我发现应该同样可行:

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. 您必须进行一些测试以查看它们是否可以线性执行,因为不能保证对ArrayList进行排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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