Skip to main content

Timeouts

If you want to stop a test after a specified amount of time, add a [Timeout] attribute onto your test method or class. This takes an int of how many milliseconds a test can execute for.

When the timeout is exceeded, the test fails and the CancellationToken is cancelled. Any operations using the token will be aborted, preventing wasted system resources on a test that has already failed.

This can be used on base classes and inherited to affect all tests in sub-classes.

Example

Pass the CancellationToken parameter to your test method to receive the timeout-linked token. Forward it to any async operations:

using TUnit.Core;

namespace MyTestProject;

public class MyTestClass
{
[Test]
[Timeout(30_000)]
public async Task Api_Responds_Within_30_Seconds(CancellationToken cancellationToken)
{
using var client = new HttpClient();

var response = await client.GetAsync("https://api.example.com/health", cancellationToken);

await Assert.That(response.IsSuccessStatusCode).IsTrue();
}
}

If the HTTP call takes longer than 30 seconds, cancellationToken is cancelled, the GetAsync call throws an OperationCanceledException, and the test is reported as failed due to timeout.

Timeout and Retries

When a test has both [Timeout] and [Retry], each retry attempt gets its own fresh timeout. If the first attempt times out at 5 seconds, the retry starts from zero with a new 5-second window:

[Test]
[Timeout(5_000)]
[Retry(2)]
public async Task Flaky_Service_Call(CancellationToken cancellationToken)
{
var result = await FlakyService.CallAsync(cancellationToken);

await Assert.That(result.Status).IsEqualTo("OK");
}

Global Timeout

In case you want to apply the timeout to all tests in a project, you can add the attribute on the assembly level.

[assembly: Timeout(30_000)]

Or you can apply the Timeout on all the tests in a class like this:

[Timeout(30_000)]
public class MyTestClass
{
}

The more specific attribute will always override the more general one. For example, the [Timeout(3000)] on a method will override the [Timeout(5000)] on the class, which in turn will override the [Timeout(7000)] on the assembly.

So the order of precedence is:

  1. Method
  2. Class
  3. Assembly