NUnittesting运行顺序

默认情况下,nunittesting按字母顺序运行。 有谁知道任何方式来设置执行顺序? 这个属性是否存在?

你的unit testing应该能够独立运行并且独立运行。 如果他们满足这个标准,那么顺序无关紧要。

然而,有些情况下你会想先运行某些testing。 一个典型的例子是在持续集成的情况下,一些testing比其他testing更长。 我们使用category属性,这样我们可以在使用数据库的testing之前运行使用模拟的testing。

即把你的快速testing开始

[Category("QuickTests")] 

如果您的testing依赖于某些环境条件,请考虑TestFixtureSetUpTestFixtureTearDown属性,这些属性允许您在testing之前和之后标记要执行的方法。

我只想指出,虽然大部分回应者都认为这些是unit testing,但问题却没有具体说明。

nUnit是一个很好的工具,可以用于各种testing情况。 我可以看到想要控制testing订单的适当理由。

在这种情况下,我不得不求助于将testing命令合并到testing名称中。 能够使用属性指定运行顺序将是非常好的。

NUnit 3.2.0增加了一个OrderAttribute ,参见:

https://github.com/nunit/docs/wiki/Order-Attribute

例:

 public class MyFixture { [Test, Order(1)] public void TestA() { ... } [Test, Order(2)] public void TestB() { ... } [Test] public void TestC() { ... } } 

要testing以特定的顺序运行并不意味着testing是相互依赖的 – 我正在开发一个TDD项目,并且是一个很好的TDDer,我嘲笑/扼杀了一切,但它会使它更具可读性,如果我可以指定testing结果显示的顺序 – 主题而不是按字母顺序。 到目前为止,我唯一能想到的就是将a_ b_ c_预先分配给类,名称空间和方法。 (不好)我认为一个[TestOrderAttribute]属性会很好 – 没有严格遵循框架,但一个提示,所以我们可以做到这一点

不pipetesting是否依赖于顺序,我们中的一些人只是想有条不紊地控制一切。

unit testing通常是按照复杂性的顺序创build的。 那么,他们为什么不能按照复杂程度或者创build顺序来运行呢?

就我个人而言,我喜欢按照创build它们的顺序来运行testing。 在TDD中,每个连续的testing自然会变得更加复杂,需要更多的时间来运行。 我宁愿看到更简单的testing首先失败,因为这将是失败原因的更好的指标。

但是,我也可以看到以随机顺序运行它们的好处,特别是如果您想testing您的testing对其他testing没有任何依赖关系。 如何添加一个选项来testing跑步者“随机运行testing,直到停止”?

我真的很喜欢以前的答案。

我改变了一点能够使用属性来设置顺序范围:

 namespace SmiMobile.Web.Selenium.Tests { using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using NUnit.Framework; public class OrderedTestAttribute : Attribute { public int Order { get; set; } public OrderedTestAttribute(int order) { Order = order; } } public class TestStructure { public Action Test; } class Int { public int I; } [TestFixture] public class ControllingTestOrder { private static readonly Int MyInt = new Int(); [TestFixtureSetUp] public void SetUp() { MyInt.I = 0; } [OrderedTest(0)] public void Test0() { Console.WriteLine("This is test zero"); Assert.That(MyInt.I, Is.EqualTo(0)); } [OrderedTest(2)] public void ATest0() { Console.WriteLine("This is test two"); MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2)); } [OrderedTest(1)] public void BTest0() { Console.WriteLine("This is test one"); MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1)); } [OrderedTest(3)] public void AAA() { Console.WriteLine("This is test three"); MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3)); } [TestCaseSource(sourceName: "TestSource")] public void MyTest(TestStructure test) { test.Test(); } public IEnumerable<TestCaseData> TestSource { get { var assembly =Assembly.GetExecutingAssembly(); Dictionary<int, List<MethodInfo>> methods = assembly .GetTypes() .SelectMany(x => x.GetMethods()) .Where(y => y.GetCustomAttributes().OfType<OrderedTestAttribute>().Any()) .GroupBy(z => z.GetCustomAttribute<OrderedTestAttribute>().Order) .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList()); foreach (var order in methods.Keys.OrderBy(x => x)) { foreach (var methodInfo in methods[order]) { MethodInfo info = methodInfo; yield return new TestCaseData( new TestStructure { Test = () => { object classInstance = Activator.CreateInstance(info.DeclaringType, null); info.Invoke(classInstance, null); } }).SetName(methodInfo.Name); } } } } } } 

我正在一个相当复杂的网站上使用Selenium进行testing,整套testing可以运行超过半小时,而且我还没有覆盖整个应用程序。 如果我必须确保所有以前的表格都正确地填写了每个testing,那么在整个testing中会花费大量的时间,而不是很less的时间。 如果运行testing的开销太大,那么人们不会经常运行它们。

所以,我把它们放在有序的位置上,并依靠以前的testing来完成文本框等。 当前提条件无效时,我使用Assert.Ignore(),但是我需要让它们按顺序运行。

我知道这是一个相对较旧的post,但是这里还有一种方法可以保持testing顺序,而不会让testing名称变得尴尬。 通过使用TestCaseSource属性并让您传入的对象具有委托(Action),您完全可以不仅控制顺序,还可以将testing命名为它的名称。

这是有效的,因为根据文档,从testing源返回的集合中的项目总是按照它们列出的顺序执行。

下面是我明天发表的一个演示:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; namespace NUnitTest { public class TestStructure { public Action Test; } class Int { public int I; } [TestFixture] public class ControllingTestOrder { private static readonly Int MyInt= new Int(); [TestFixtureSetUp] public void SetUp() { MyInt.I = 0; } [TestCaseSource(sourceName: "TestSource")] public void MyTest(TestStructure test) { test.Test(); } public IEnumerable<TestCaseData> TestSource { get { yield return new TestCaseData( new TestStructure { Test = () => { Console.WriteLine("This is test one"); MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1)); } }).SetName(@"Test One"); yield return new TestCaseData( new TestStructure { Test = () => { Console.WriteLine("This is test two"); MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2)); } }).SetName(@"Test Two"); yield return new TestCaseData( new TestStructure { Test = () => { Console.WriteLine("This is test three"); MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3)); } }).SetName(@"Test Three"); } } } } 

我正在使用用C#编写的使用NUnit框架运行的Selenium WebDriver端到端UItesting案例。 (不是单位案例)

这些UItesting肯定取决于执行顺序,因为其他testing需要添加一些数据作为先决条件。 (在每个testing中都要做到这一点是不可行的)

现在,在添加第十个testing用例之后,我看到NUnit希望按以下顺序运行:Test_1 Test_10 Test_2 Test_3 ..

所以我想我现在也必须将testing用例名称字母化,但是将这个控制执行顺序的小特性添加到NUnit中会是一件好事。

通常unit testing应该是独立的,但是如果你必须的话,你可以按字母顺序命名你的方法例如:

 [Test] public void Add_Users(){} [Test] public void Add_UsersB(){} [Test] public void Process_Users(){} 

或者你可以做..

  private void Add_Users(){} private void Add_UsersB(){} [Test] public void Process_Users() { Add_Users(); Add_UsersB(); // more code } 

使用testing订单机制有很好的理由。 我自己的大多数testing都使用了很好的练习,比如设置/拆卸。 其他需要大量的数据设置,然后可以用来testing一系列function。 到目前为止,我已经使用了大量的testing来处理这些(Selenium Webdriver)集成testing。 不过,我认为上面提到的https://github.com/nunit/docs/wiki/Order-Attribute上的post有很多优点。; 下面是为什么sorting非常有价值的一个例子:

  • 使用Selenium Webdriver运行testing来下载报告
  • 报告的状态(无论是否可下载)被caching10分钟
  • 这意味着,在每次testing之前,我需要重置报告状态,然后在状态确认更改之前等待最多10分钟 ,然后validation报告是否正确下载。
  • 由于testing框架的复杂性,无法通过嘲讽或任何其他机制以实际/及时的方式生成报告。

这10分钟的等待时间会减慢testing套件的速度。 当您在多个testing中使用相似的caching延迟时,会消耗大量时间。 sortingtesting可以允许在testing套件开始时将数据设置作为“testing”来完成,testing依赖于高速caching在testing运行结束时不能执行。

这个问题现在真的很老了,但是对于那些可能从search中得到的人来说,我从user3275​​462和PvtVandals / Rico中得到了很好的答案,并把它们和我自己的一些更新一起添加到GitHub仓库中 。 我还创build了一个关联的博客文章 ,您可以查看更多信息。

希望这对你们有所帮助。 另外,我经常喜欢使用Category属性来区分我的集成testing或其他端对端的testing。 其他人指出,unit testing不应该具有顺序依赖性,但是其他testingtypes通常会这样做,所以这提供了一个很好的方法来运行你想要的testing类别,并且命令那些端到端的testing。

我很惊讶NUnit社区没有提出任何东西,所以我自己去创build这样的东西。

我目前正在开发一个开源库 ,允许你用NUnit命令你的testing。 您可以订购testing夹具并订购“订购testing规格”。

该库提供以下function:

  • 构build复杂的testing订购层次结构
  • 如果顺序testing失败,则跳过后续testing
  • 按照依赖性而不是整数顺序排列你的testing方法
  • 支持与无序testing并行使用。 无序testing首先执行。

这个库实际上是启发了MSTest如何使用.orderedtest文件testingsorting。 请看下面的例子。

 [OrderedTestFixture] public sealed class MyOrderedTestFixture : TestOrderingSpecification { protected override void DefineTestOrdering() { TestFixture<Fixture1>(); OrderedTestSpecification<MyOtherOrderedTestFixture>(); TestFixture<Fixture2>(); TestFixture<Fixture3>(); } protected override bool ContinueOnError => false; // Or true, if you want to continue even if a child test fails } 

您不应该依赖testing框架selecttesting执行的顺序。 testing应该是孤立的和独立的。 在那里,他们不应该依赖于其他的testing设置他们的舞台或后来清理。 他们也应该产生相同的结果,而不pipetesting的执行顺序(对于SUT的给定快照)

我做了一些Googlesearch。 像往常一样,一些人采取了偷偷摸摸的技巧(而不是解决潜在的可testing性/devise问题

  • 以按字母顺序排列的方式命名testing,以便testing以“需要”执行的顺序出现。 然而,NUnit可能会select使用更高版本更改此行为,然后您的testing将被彻底清除。 更好地检查当前的NUnit二进制文件到源代码pipe理。
  • VS(恕我直言,用他们的“敏捷工具”鼓励错误的行为)在他们的MStesting框架中有一些叫做“有序testing”的东西。 我没有浪费时间阅读,但似乎是针对相同的观众

另见: 一个很好的testing的特点