'How does XUnit RetryFact attribute works?

I have Selenium tests which are run by XUnit. I write tests on c#. Some of the tests are not stable (especially those which uses mouse actions). I found the RetryFactAttribute in XUnit but I can't find any documetation for it.

My main question for now: will xUnit run other tests while waiting 3 seconds if I use [RetryFact(delayBetweenRetriesMs: 3000)] ?

If you can, please suggest resource where I can find more information about the attribute.



Solution 1:[1]

It appears to be an example of how to use a custom IXunitTestCaseDiscoverer and XunitTestCase. You can find the example source code here.

Ultimately it's just an attribute with the following attribute attached to it:

[XunitTestCaseDiscoverer("RetryFactExample.RetryFactDiscoverer", "RetryFactExample")]

Which then indirectly references RetryTestCase.cs (a derivative of XunitTestCase) where its actual behaviour is defined:

public override async Task<RunSummary> RunAsync(IMessageSink diagnosticMessageSink,
                                                IMessageBus messageBus,
                                                object[] constructorArguments,
                                                ExceptionAggregator aggregator,
                                                CancellationTokenSource cancellationTokenSource)
{
    var runCount = 0;

    while (true)
    {
        // This is really the only tricky bit: we need to capture and delay messages (since those will
        // contain run status) until we know we've decided to accept the final result;
        var delayedMessageBus = new DelayedMessageBus(messageBus);

        var summary = await base.RunAsync(diagnosticMessageSink, delayedMessageBus, constructorArguments, aggregator, cancellationTokenSource);
        if (aggregator.HasExceptions || summary.Failed == 0 || ++runCount >= maxRetries)
        {
            delayedMessageBus.Dispose();  // Sends all the delayed messages
            return summary;
        }

        diagnosticMessageSink.OnMessage(new DiagnosticMessage("Execution of '{0}' failed (attempt #{1}), retrying...", DisplayName, runCount));
    }
}

I'm not 100% sure about your question re whether it will block on a single test for 3 seconds, but judging by this I think the answer is probably "yes". It's best to test this experimentally to be sure.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pankaj