如何在xUnit中同步运行的测试?

时间:2018-05-25 01:57:06

标签: c# testing nunit xunit

我需要并行启动数十个测试用例,但是有一个问题 - 所有这些都达到了一个单一操作应该只执行一次的程度,无论运行多少个测试用例。一旦此操作结束,测试可以恢复并继续独立运行。

现在我在NUnit中有以下实现:

[TestFixture]
public class ScheduleJobTest
{
    private static readonly Subject<Unit> s_tickets = new Subject<Unit>();

    [OneTimeSetUp]
    public static void SetUp()
    {
        Task.Run(() => s_tickets
            .Throttle(TimeSpan.FromSeconds(1))
            .SelectMany(_ => PollSchedulesNow())
            .DefaultIfEmpty()
            .GetAwaiter()
            .GetResult());
    }

    [OneTimeTearDown]
    public static void TearDown()
    {
        s_tickets.OnCompleted();
    }

    private static IObservable<Unit> PollSchedulesNow()
    {
        // Do something that eventually unblocks all the test cases
    }

    [TestCaseSource(nameof(ProvideNamespaces)), Parallelizable(ParallelScope.Children)]
    public void ScheduleJob(NamespaceConnectionInfo nci)
    {
        // Do something
        s_tickets.OnNext(Unit.Default);
        // Resume - blocks until the actions of PollSchedulesNow take effect
    }

    private static IEnumerable<TestCaseData> ProvideNamespaces()
    {
        return ...
    }
}

每个测试用例都会为应该只执行一次的特殊操作排队一张票。限制确保只要门票在最多一秒钟内到达,就不会发生任何事情。但是一旦暂停发生,它就会触发特殊操作。如果由于某种原因,在暂停后会有更多测试用例,那么将再次调用特殊操作 - 这很好。我只是不希望它被同时运行的100个并发测试用例调用100次。

这是我在NUnit中想到的最好的。有没有更好的方法在xUnit中实现它?或者我可能首先需要一个不同的框架?

1 个答案:

答案 0 :(得分:0)

首先关闭:不会。除非你在测试中自己编写协调代码,否则NUnit无法协调各个测试。即使这样,你也必须确保NUnit将所有这些组合在一起运行,如果没有你的帮助,它可能会也可能不会。

但是!你可以完成你想要的。您正在尝试使用多个NUnit测试来模拟跨多个线程的基本单个测试。别这么做!编写一个测试,根据需要生成尽可能多的单独线程。等待它们完成,然后验证该操作仅执行一次。这里只有一个断言,证明只有一个测试。

您可以根据需要多次为不同数量的线程和错误条件重复此操作。每个变体都是单一测试。