<PackageReference Include="NUnit" Version="4.5.0" />

RetryAttribute

Specifies that a test method should be rerun on failure up to the specified maximum number of times.
using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Commands; using System; using System.Runtime.CompilerServices; namespace NUnit.Framework { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public class RetryAttribute : NUnitAttribute, IRepeatTest, ICommandWrapper { [System.Runtime.CompilerServices.Nullable(0)] public class RetryCommand : DelegatingTestCommand { private readonly int _tryCount; private readonly Type[] _retryExceptions; public RetryCommand(TestCommand innerCommand, int tryCount) : this(innerCommand, tryCount, Array.Empty<Type>()) { } public RetryCommand(TestCommand innerCommand, int tryCount, Type[] retryExceptions) : base(innerCommand) { _tryCount = tryCount; _retryExceptions = retryExceptions; } public override TestResult Execute(TestExecutionContext context) { int num = _tryCount; while (num-- > 0) { Exception ex = null; try { context.CurrentResult = innerCommand.Execute(context); } catch (Exception exception) { ex = exception.Unwrap(); if (context.CurrentResult == null) context.CurrentResult = context.CurrentTest.MakeTestResult(); } if (ex != null && !(ex is ResultStateException) && (num == 0 || !IsRetryException(ex))) { context.CurrentResult.RecordException(ex); break; } if (context.CurrentResult.ResultState != ResultState.Failure && !IsRetryException(context.CurrentResult.RecordedException)) break; if (num > 0) { context.CurrentResult = context.CurrentTest.MakeTestResult(); context.CurrentRepeatCount++; } } return context.CurrentResult; } [System.Runtime.CompilerServices.NullableContext(2)] private bool IsRetryException(Exception ex) { if (ex == null) return false; Type type = ex.GetType(); Type[] retryExceptions = _retryExceptions; foreach (Type type2 in retryExceptions) { if (type2.IsAssignableFrom(type)) return true; } return false; } } private readonly int _tryCount; public Type[] RetryExceptions { get; set; } = Array.Empty<Type>(); public RetryAttribute(int tryCount) { _tryCount = tryCount; } public TestCommand Wrap(TestCommand command) { return new RetryCommand(command, _tryCount, RetryExceptions); } } }