23

I have integration tests set up with xUnit.net.

Is there a way to configure how long an integration test should last maximum? I mean a threshold.

1
  • 1
    Probably not available at the time, but dotnet test --blame-hang-timeout 30s would be another way to disallow any single test to run longer than 30 seconds. It is not controlled by xUnit, but by the test runner, and can be used with any framework and doesn't suffer the issues with Fact(Timeout=30000ms), which xUnit most of the time just ignores... Commented Oct 16, 2022 at 16:59

4 Answers 4

20

For the newer xunit versions, I am using this method, which seems to work well:

public static class AssertAsync
{
    public static void CompletesIn(int timeout, Action action)
    {
        var task = Task.Run(action);
        var completedInTime = Task.WaitAll(new[] { task }, TimeSpan.FromSeconds(timeout));

        if (task.Exception != null)
        {
            if (task.Exception.InnerExceptions.Count == 1)
            {
                throw task.Exception.InnerExceptions[0];
            }

            throw task.Exception;
        }

        if (!completedInTime)
        {
            throw new TimeoutException($"Task did not complete in {timeout} seconds.");
        }
    }
}

You can use it like so:

[Fact]
public void TestMethod()
{
    AssertAsync.CompletesIn(2, () =>
    {
        RunTaskThatMightNotComplete();
    });
}

However, be sure to read the reason about why this was removed in the first place as one of the maintainers of the project does make a pretty good point about potentially deadlocking your test run. I run these tests in single-threaded mode and it doesn't appear to cause a problem.

Sign up to request clarification or add additional context in comments.

1 Comment

Looks like xUnit again supports [Fact(Timeout=milliseconds)], but only for non-parallel runs.
16

It seems, what you are looking for is the Timeout parameter of the Fact attribute.

For further information see the XUnit Docs under Ensuring a Test Does Not Run Too Long.

3 Comments

The answer is not helpful at all. The link leads to a documentation page, but not to a specifc article. While, the specific article on the Fact parameters seems to be absent in the documentation whatsoever.
I believe that it is necessary to add a link to a specific article from the documentation on the Fact and add an excerpt from the article here.
WARNING: Using this with parallelization turned on will result in undefined behavior. Timeout is only supported when parallelization is disabled, either globally or with a parallelization-disabled test collection.
11

Unfortunately, in newer versions it looks like the Fact attribute no longer has a Timeout parameter

3 Comments

Do you know if there are any extensions that add this feature back in?
Not that I know of. I am not very familiar with it but reading a discussion thread it was removed for purity. The argument being that with thread scheduling and such it was impossible to guarantee it was accurate.
I think they brought it back in 2.4 but for parallel execution, it's behavior is "undefined"
9

To get a concrete example:

You can just use

[Fact(Timeout = 2000)]

for example.

Hint: Timeout is specified in ms.

1 Comment

Please note that as of the date of posting this comment the Timeout attribute only works for async methods. github.com/xunit/xunit/issues/2222

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.