using System; using Xunit; using Xunit.Abstractions; using Xunit.Sdk; namespace Berufsschule_HAM.E2ETests; public class RetryFactAttribute(int maxRetries = 5) : FactAttribute { public int MaxRetries { get; } = maxRetries; } public class RetryTestCase : XunitTestCase { private int _maxRetries; [Obsolete("Called by the de-serializer", true)] public RetryTestCase() { } public RetryTestCase( IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, TestMethodDisplayOptions defaultMethodDisplayOptions, ITestMethod testMethod, int maxRetries) : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod) { _maxRetries = maxRetries; } public override async Task RunAsync( IMessageSink diagnosticMessageSink, IMessageBus messageBus, object[] constructorArguments, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) { var summary = new RunSummary(); for (int i = 1; i <= _maxRetries; i++) { var result = await base.RunAsync( diagnosticMessageSink, messageBus, constructorArguments, aggregator, cancellationTokenSource); summary.Aggregate(result); if (result.Failed == 0) break; // success, stop retrying } return summary; } } public class RetryFactDiscoverer : IXunitTestCaseDiscoverer { private readonly IMessageSink _diagnosticMessageSink; public RetryFactDiscoverer(IMessageSink diagnosticMessageSink) { _diagnosticMessageSink = diagnosticMessageSink; } public IEnumerable Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) { var maxRetries = factAttribute.GetNamedArgument("MaxRetries"); yield return new RetryTestCase( _diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, maxRetries); } }