.net NUnit 测试运行顺序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1078658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NUnit Test Run Order
提问by Riain McAtamney
By default nunit tests run alphabetically. Does anyone know of any way to set the execution order? Does an attribute exist for this?
默认情况下,nunit 测试按字母顺序运行。有谁知道设置执行顺序的任何方法?是否存在此属性?
采纳答案by NeedHack
Your unit tests should each be able to run independently and stand alone. If they satisfy this criterion then the order does not matter.
你的单元测试应该能够独立运行。如果它们满足此标准,则顺序无关紧要。
There are occasions however where you will want to run certain tests first. A typical example is in a Continuous Integration situation where some tests are longer running than others. We use the category attribute so that we can run the tests which use mocking ahead of the tests which use the database.
然而,在某些情况下,您需要先运行某些测试。一个典型的例子是在持续集成情况下,一些测试比其他测试运行时间更长。我们使用 category 属性,以便我们可以在使用数据库的测试之前运行使用模拟的测试。
i.e. put this at the start of your quick tests
即把它放在你的快速测试的开始
[Category("QuickTests")]
Where you have tests which are dependant on certain environmental conditions, consider the TestFixtureSetUpand TestFixtureTearDownattributes, which allow you to mark methods to be executed before and after your tests.
如果您的测试依赖于某些环境条件,请考虑TestFixtureSetUp和TestFixtureTearDown属性,它们允许您标记要在测试之前和之后执行的方法。
回答by Les
I just want to point out that while most of the responders assumed these were unit tests, the question did not specify that they were.
我只想指出,虽然大多数响应者认为这些是单元测试,但问题并没有具体说明它们是。
nUnit is a great tool that can be used for a variety of testing situations. I can see appropriate reasons for wanting to control test order.
nUnit 是一个很棒的工具,可用于各种测试情况。我可以看到想要控制测试订单的适当理由。
In those situations I have had to resort to incorporating a run order into the test name. It would be great to be able to specify run order using an attribute.
在这些情况下,我不得不求助于将运行顺序合并到测试名称中。能够使用属性指定运行顺序会很棒。
回答by R?zvan Flavius Panda
NUnit 3.2.0 added an OrderAttribute, see:
NUnit 3.2.0 添加了一个OrderAttribute,参见:
https://github.com/nunit/docs/wiki/Order-Attribute
https://github.com/nunit/docs/wiki/Order-Attribute
Example:
例子:
public class MyFixture
{
[Test, Order(1)]
public void TestA() { ... }
[Test, Order(2)]
public void TestB() { ... }
[Test]
public void TestC() { ... }
}
回答by William
Wanting the tests to run in a specific order does not mean that the tests are dependent on each other - I'm working on a TDD project at the moment, and being a good TDDer I've mocked/stubbed everything, but it would make it more readable if I could specify the order which the tests results are displayed- thematically instead of alphabetically. So far the only thing I can think of is to prepend a_ b_ c_ to classes to classes, namespaces and methods. (Not nice) I think a [TestOrderAttribute] attribute would be nice - not stricly followed by the framework, but a hint so we can achieve this
希望测试按特定顺序运行并不意味着测试相互依赖——我目前正在做一个 TDD 项目,作为一名优秀的 TDDer 我已经嘲笑/存根了一切,但这会让如果我可以指定显示测试结果的顺序 - 按主题而不是按字母顺序,它更具可读性。到目前为止,我唯一能想到的就是将 a_ b_ c_ 添加到类、名称空间和方法的类中。(不好)我认为 [TestOrderAttribute] 属性会很好 - 框架没有严格遵循,而是一个提示,因此我们可以实现这一目标
回答by Mont Pierce
Regardless of whether or not Tests are order dependent... some of us just want to control everything, in an orderly fashion.
不管测试是否依赖于顺序......我们中的一些人只想以有序的方式控制一切。
Unit tests are usually created in order of complexity. So, why shouldn't they also be run in order of complexity, or the order in which they were created?
单元测试通常按照复杂性的顺序创建。那么,为什么不应该按照复杂性或创建它们的顺序运行它们呢?
Personally, I like to see the tests run in the order of which I created them. In TDD, each successive test is naturally going to be more complex, and take more time to run. I would rather see the simpler test fail first as it will be a better indicator as to the cause of the failure.
就我个人而言,我喜欢看到测试按照我创建它们的顺序运行。在 TDD 中,每个连续的测试自然会变得更加复杂,并且需要更多的时间来运行。我宁愿看到更简单的测试首先失败,因为它将是关于失败原因的更好指标。
But, I can also see the benefit of running them in random order, especially if you want to test that your tests don't have any dependencies on other tests. How about adding an option to test runners to "Run Tests Randomly Until Stopped"?
但是,我也可以看到以随机顺序运行它们的好处,特别是如果您想测试您的测试是否与其他测试没有任何依赖关系。添加一个选项来测试运行器“随机运行测试直到停止”如何?
回答by PvtVandals
I really like the previous answer.
我真的很喜欢以前的答案。
I changed it a little to be able to use an attribute to set the order range:
我对其进行了一些更改,以便能够使用属性来设置订单范围:
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);
}
}
}
}
}
}
回答by Anthony Biagioli
I am testing with Selenium on a fairly complex web site and the whole suite of tests can run for more than a half hour, and I'm not near to covering the entire application yet. If I have to make sure that all previous forms are filled in correctly for each test, this adds a great deal of time, not just a small amount of time, to the overall test. If there's too much overhead to running the tests, people won't run them as often as they should.
我正在一个相当复杂的网站上使用 Selenium 进行测试,整个测试套件可以运行半个多小时,而且我还没有接近覆盖整个应用程序。如果我必须确保每次测试都正确填写所有以前的表格,这会为整个测试增加大量时间,而不仅仅是少量时间。如果运行测试的开销太大,人们就不会像他们应该的那样经常运行它们。
So, I put them in order and depend on previous tests to have text boxes and such completed. I use Assert.Ignore() when the pre-conditions are not valid, but I need to have them running in order.
因此,我将它们按顺序排列并依赖于之前的测试来完成文本框等。当前提条件无效时,我使用 Assert.Ignore(),但我需要让它们按顺序运行。
回答by Dave Bush
I know this is a relatively old post, but here is another way to keep your test in order WITHOUT making the test names awkward. By using the TestCaseSource attribute and having the object you pass in have a delegate (Action), you can totally not only control the order but also name the test what it is.
我知道这是一篇相对较旧的帖子,但这里有另一种方法可以让您的测试井井有条,而不会让测试名称变得尴尬。通过使用 TestCaseSource 属性并让您传入的对象具有委托(Action),您不仅可以完全控制顺序,还可以为测试命名。
This works because, according to the documentation, the items in the collection returned from the test source will always execute in the order they are listed.
这是有效的,因为根据文档,从测试源返回的集合中的项目将始终按照它们列出的顺序执行。
Here is a demo from a presentation I'm giving tomorrow:
这是我明天要进行的演示的演示:
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");
}
}
}
}
回答by Hexa
I am working with Selenium WebDriver end-to-end UI test cases written in C#, which are run using NUnit framework. (Not unit cases as such)
我正在使用用 C# 编写的 Selenium WebDriver 端到端 UI 测试用例,这些用例使用 NUnit 框架运行。(不是这样的单位案例)
These UI tests certainly depend on order of execution, as other test needs to add some data as a precondition. (It is not feasible to do the steps in every test)
这些 UI 测试当然取决于执行顺序,因为其他测试需要添加一些数据作为前提条件。(不可能每次测试都做步骤)
Now, after adding the 10th test case, i see NUnit wants to run in this order: Test_1 Test_10 Test_2 Test_3 ..
现在,在添加第 10 个测试用例后,我看到 NUnit 想要按以下顺序运行: Test_1 Test_10 Test_2 Test_3 ..
So i guess i have to too alphabetisize the test case names for now, but it would be good to have this small feature of controlling execution order added to NUnit.
所以我想我现在必须将测试用例名称按字母顺序排列,但是将这个控制执行顺序的小功能添加到 NUnit 会很好。
回答by Sebastian Castaldi
Usually Unit Test should be independent, but if you must, then you can name your methods in alphabetical order ex:
通常单元测试应该是独立的,但如果你必须,那么你可以按字母顺序命名你的方法,例如:
[Test]
public void Add_Users(){}
[Test]
public void Add_UsersB(){}
[Test]
public void Process_Users(){}
or you can do..
或者你可以做..
private void Add_Users(){}
private void Add_UsersB(){}
[Test]
public void Process_Users()
{
Add_Users();
Add_UsersB();
// more code
}

