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

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 { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.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 { Task<TestResult> task = RunTestOnSeparateThread(context); if (Task.WaitAny(new Task[1] { task }, _timeout) != -1 || _debugger.IsAttached) context.CurrentResult = task.GetAwaiter().GetResult(); else { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(33, 1); defaultInterpolatedStringHandler.AppendLiteral("Test exceeded Timeout value of "); defaultInterpolatedStringHandler.AppendFormatted(_timeout); defaultInterpolatedStringHandler.AppendLiteral("ms"); string message = defaultInterpolatedStringHandler.ToStringAndClear(); context.CurrentResult.SetResult(ResultState.Failure, message); } } catch (Exception ex) { context.CurrentResult.RecordException(ex, FailureSite.Test); } return context.CurrentResult; } private Task<TestResult> RunTestOnSeparateThread(TestExecutionContext context) { TestExecutionContext separateContext = new TestExecutionContext(context) { CurrentResult = context.CurrentTest.MakeTestResult() }; return Task.Run(() => innerCommand.Execute(separateContext)); } } }