C# 如何使用NUnit强制visual studio中的最后一次测试运行

C# 如何使用NUnit强制visual studio中的最后一次测试运行,c#,unit-testing,nunit,C#,Unit Testing,Nunit,因此,在我的测试套件中,我有一个抽象基类,我的集成测试从中继承。这个基类的每个派生都有自己的测试集。子类所做的断言是通过基类上的受保护方法运行的。在这些断言期间,基类会记录字典中哪些值已经过测试。在子类运行了所有的测试之后,我希望基类运行一个测试来验证所有正确的测试 一些免责声明: 是的,我知道这是一个有序的测试,那些都是皱眉的 在上面然而,这是我无论如何都想做的事情 从某种意义上说,我知道这是一个测试我的测试套件的测试。虽然这是 我经常皱眉头,觉得它很有用。如果你想让你的测试 真正成为你的文档

因此,在我的测试套件中,我有一个抽象基类,我的集成测试从中继承。这个基类的每个派生都有自己的测试集。子类所做的断言是通过基类上的受保护方法运行的。在这些断言期间,基类会记录字典中哪些值已经过测试。在子类运行了所有的测试之后,我希望基类运行一个测试来验证所有正确的测试

一些免责声明:

  • 是的,我知道这是一个有序的测试,那些都是皱眉的 在上面然而,这是我无论如何都想做的事情
  • 从某种意义上说,我知道这是一个测试我的测试套件的测试。虽然这是 我经常皱眉头,觉得它很有用。如果你想让你的测试 真正成为你的文档,有一些基础知识是很好的 验证有关文档的一些基本内容的测试 例如,它是完整的。(在大多数项目中,这可能会 太过分了,不值得。但是在这个特殊的项目中, 这既是一个个人项目,也是一个与100%合作的实验 代码覆盖率。)
  • 现在,我已经用
    [test]
    [TestFixtureTearDown]
    标记了摘要测试,这确实使测试在最后运行。然而,这也意味着当测试失败时,测试套件会因为拆卸失败而生气。在理想的世界里,我想要的是[最后一次跑步]。有没有关于如何才能做到这一点的想法

    当前代码的示例:

    [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);
        }
    }
    
    [TestFixture]
    公共抽象类属性测试:集成测试
    {
    [注入]
    公共IAttributesMapper属性映射器{get;set;}
    受保护的抽象字符串表名{get;}
    专用字典表;
    私人名单测试姓名;
    [TestFixtureSetUp]
    public void FixtureSetup()
    {
    testedNames=新列表();
    }
    [设置]
    公共作废设置()
    {
    table=属性映射(tableName);
    }
    [测试,测试固定器拆卸]
    public void allnamested()
    {
    var missingNames=table.Keys.Except(testedNames);
    Assert.That(missingNames,Is.Empty,tableName);
    }
    [测试,测试固定器拆卸]
    public void NoNameTestedMultipleTimes()
    {
    var duplicateNames=testedNames.Where(n=>testedNames.Count(cn=>cn==n)>1.Distinct();
    Assert.That(duplicateNames,Is.Empty,tableName);
    }
    受保护的void AssertAttribute(字符串名称、IEnumerable属性)
    {
    测试名称。添加(名称);
    Assert.That(table.Keys,Contains.Item(name),tableName);
    foreach(属性中的var属性)
    {
    Assert.That(表[name],包含.Item(属性));
    var actualAttributeCount=表[name].Count(a=>a==属性);
    var expectedAttributeCount=attributes.Count(a=>a==attribute);
    Assert.That(actualAttributeCount,Is.EqualTo(expectedAttributeCount));
    }
    var extraAttributes=表[name]。除了(属性);
    Assert.That(extraAttributes,Is.Empty);
    }
    }
    
    我知道没有明确的类似于
    [lastest]
    的属性,但我相信您可以选择
    [Suite]

    我知道这种JUnit套件方法将按照定义的lineair顺序执行测试类(尽管不能保证在一个类中执行测试的顺序)

    此处将最后执行
    CalculatorTestSubtract
    。记住这一点,我想说您应该创建一个套件,它在最后有您的摘要测试

    看一看,我发现有些事情应该是同样可能的:

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

    这对我很有用:

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

    因此在我的例子中,总结测试应该在基类的每个派生中的所有测试之后运行-如果基类有三个具体的派生,那么测试应该在每个派生完成其测试之后运行(因此测试的三个实例,基本上,直接与基类的具体实现联系在一起)。我担心的是,套件方法会使摘要测试与具体实现过于脱节。您必须记住在套件中按正确的顺序放置它们,它们必须位于不同的类中,但据我所知,这是唯一的解决方案。NUnit的一个特点是您可以选择,在逐个运行的基础上,运行哪些特定的测试,因此您不能总是保证所有测试都将运行。这是真的,我确实有一些情况下,我在类中部分运行了测试,因此摘要测试失败。记住这一点,任何时候运行给定测试类中的所有测试(更不用说整个测试套件了),这些测试都会很好。因此,虽然肯定不是理想的,但这不是一个可怕的问题(在我看来,至少目前是这样),所以本质上,您正在向测试套件添加一个代码覆盖率度量,它应该在完整运行时报告100%,但(可以接受)比部分运行时报告的要少?确切地说。这当然不是最佳实践——我正在做的项目是一个测试、TDD和100%覆盖率的实验。所以我在玩弄一些东西。:)Nunit将主要按照字母顺序执行测试用例。因此,名称以z开头将使您的测试用例在最后运行。:)简单但令人敬畏的修复
    namespace ZZZ
    public class ZZZZZ {
      [Test]
      public void ZZZZLastTest() {
        // Whatever . . . 
      }
    }