运行长时间运行的NUnit/xUnit测试,以便它们不会阻塞其他测试
我正在运行一组集成测试,虽然大多数测试都在合理的时间内完成,但有两个测试正在等待特定条件(金融市场条件要精确),它们可以持续2-3个小时。因此,理想情况下,我希望实现两件事:运行长时间运行的NUnit/xUnit测试,以便它们不会阻塞其他测试,nunit,xunit,Nunit,Xunit,我正在运行一组集成测试,虽然大多数测试都在合理的时间内完成,但有两个测试正在等待特定条件(金融市场条件要精确),它们可以持续2-3个小时。因此,理想情况下,我希望实现两件事: 在其他测试完成后开始这两个测试 并行运行它们 在NUnit/XUnit(或其他测试运行程序)中是否有实现这一点的方法 并行测试运行取决于测试运行程序的参数,如果您使用的是xUnit控制台测试运行程序,则存在-Parallel参数或MSBuild选项,请参阅:。但是在任何情况下,您都必须在单独的测试类上拆分长时间运行的测试
- 使用Parallelizable属性标记测试夹具,并将并行范围设置为ParallelScope.All
- 创建一个名为TestScope的私有类并实现IDisposable
- 将所有启动和清理逻辑分别放在TestScope构造函数和.Dispose()方法中
- 将测试代码包装在using(var scope=newtestscope){…}块中
[TestFixture]
[可并行化(ParallelScope.All)]
公共类MyClassTests{
[测试]
公共无效MyParallelTest(){
使用(var scope=newtestscope()){
scope.Sut.DoSomething();
scope.Repository.Received(1.Save();
}
}
私有密封类TestScope:IDisposable{
公共IRepository存储库{get;}
公共MyClass Sut{get;}
公共测试范围(){
Repository=replacement.For();
Sut=新的MyClass(存储库);
}
公共空间处置(){
//清理代码在这里
存储库?.Dispose()
}
}
}
您应该采取预防措施,以确保并行运行时,测试不会相互干扰
如该条所述:
如何安全地并行运行测试
允许测试并行运行
在没有他们相互干扰的情况下,我一直在应用
下面是一段时间的模式:
- 创建实现IDisposable的嵌套私有TestScope类
- 将进入安装方法的所有初始化或启动代码 进入TestScope类的构造函数
- 任何清理或 将进入拆卸方法的拆卸代码将进入 Dispose方法所有测试都在处理 TestScope的创建和处置
[TestFixture]
[可并行化(ParallelScope.All)]
公共类MyClassTests{
[测试]
公共无效MyParallelTest(){
使用(var scope=newtestscope()){
scope.Sut.DoSomething();
scope.Repository.Received(1.Save();
}
}
私有密封类TestScope:IDisposable{
公共IRepository存储库{get;}
公共MyClass Sut{get;}
公共测试范围(){
Repository=replacement.For();
Sut=新的MyClass(存储库);
}
公共空间处置(){
//清理代码在这里
存储库?.Dispose()
}
}
}
这篇文章提供了更有价值的建议。我建议您阅读并感谢作者。您可以在不同的过程中运行测试
[TestFixture]
[Parallelizable(ParallelScope.All)]
public class MyClassTests {
[Test]
public void MyParallelTest() {
using(var scope = new TestScope()) {
scope.Sut.DoSomething();
scope.Repository.Received(1).Save();
}
}
private sealed class TestScope : IDisposable {
public IRepository Repository{get;}
public MyClass Sut {get;}
public TestScope() {
Repository = Substitute.For<IRepository>();
Sut = new MyClass(Repository);
}
public void Dispose() {
//clean-up code goes here
Repository?.Dispose()
}
}
}
[TestFixture]
[Parallelizable(ParallelScope.All)]
public class MyClassTests {
[Test]
public void MyParallelTest() {
using(var scope = new TestScope()) {
scope.Sut.DoSomething();
scope.Repository.Received(1).Save();
}
}
private sealed class TestScope : IDisposable {
public IRepository Repository{get;}
public MyClass Sut {get;}
public TestScope() {
Repository = Substitute.For<IRepository>();
Sut = new MyClass(Repository);
}
public void Dispose() {
//clean-up code goes here
Repository?.Dispose()
}
}
}