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

TimeoutCommand

TimeoutCommand creates a timer in order to cancel a test if it exceeds a specified time and adjusts the test result if it did time out.
using NUnit.Framework.Interfaces; using NUnit.Framework.Internal.Abstractions; using System; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace NUnit.Framework.Internal.Commands { [NullableContext(1)] [Nullable(0)] public class TimeoutCommand : BeforeAndAfterTestCommand { private readonly int _timeout; private readonly IDebugger _debugger; internal TimeoutCommand(TestCommand innerCommand, int timeout, IDebugger debugger) : base(innerCommand) { _timeout = timeout; _debugger = debugger; Guard.ArgumentValid(innerCommand.Test is TestMethod, "TimeoutCommand may only apply to a TestMethod", "innerCommand"); Guard.ArgumentValid(timeout > 0, "Timeout value must be greater than zero", "timeout"); Guard.ArgumentNotNull(debugger, "debugger"); BeforeTest = delegate { }; AfterTest = delegate { }; } public override TestResult Execute(TestExecutionContext context) { try { using (new TestExecutionContext.IsolatedContext()) { Task<TestResult> task = Task.Run(() => innerCommand.Execute(TestExecutionContext.CurrentContext)); if (Task.WaitAny(new Task[1] { task }, _timeout) == -1 && !_debugger.IsAttached) { TestResult currentResult = context.CurrentResult; ResultState failure = ResultState.Failure; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(33, 1); defaultInterpolatedStringHandler.AppendLiteral("Test exceeded Timeout value of "); defaultInterpolatedStringHandler.AppendFormatted(_timeout); defaultInterpolatedStringHandler.AppendLiteral("ms"); currentResult.SetResult(failure, defaultInterpolatedStringHandler.ToStringAndClear()); } else context.CurrentResult = task.GetAwaiter().GetResult(); } } catch (Exception ex) { context.CurrentResult.RecordException(ex, FailureSite.Test); } return context.CurrentResult; } } }