Skip to content

Commit e73ee38

Browse files
committed
Update cancelafter.md to clarify cancellation token usage (#1144)
* Update cancelafter.md to clarify cancellation token usage Clarify that the cancellation token is available across all execution phases. * Enhance documentation on cancellation token usage Clarify the behavior of cancellation tokens in TearDown phases and their implications for cleanup methods. * Apply suggestion from @stevenaw e74521d
1 parent fc8ae61 commit e73ee38

3 files changed

Lines changed: 729 additions & 725 deletions

File tree

articles/nunit/writing-tests/attributes/cancelafter.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ <h1 id="cancelafter">CancelAfter</h1>
102102
<p>The specified timeout value covers the test setup and teardown as well as the test method itself. Before and after
103103
actions may also be included, depending on where they were specified. Since the timeout may occur during any of these
104104
execution phases, no guarantees can be made as to what will be run and any of these phases of execution may be
105-
incomplete. If only used on a test, once a test has timed out, its teardown methods are executed.</p>
105+
incomplete. If only used on a test, once a test has timed out, its teardown methods are executed. NUnit will ensure
106+
that the cancellation token will be available across all these phases. This also means that the token will be in the
107+
&quot;cancelled&quot; state in one phase (ex: <code>TearDown</code>) if it were marked as cancelled during a previous phase. It therefore
108+
should be used with caution in <code>TearDown</code> phases when getting passed down to other methods which perform cleanup as
109+
an already-cancelled token may prevent HTTP or DB calls from being performed.</p>
106110
<p>The attribute may also be specified on a fixture, in which case it indicates the default timeout for any subordinate
107111
test cases. When using the console runner, it is also possible to specify a default timeout on the command-line.</p>
108112
<p>When used on test methods, NUnit automatically adds an extra argument to your method containing the NUnit

index.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2997,7 +2997,7 @@
29972997
"articles/nunit/writing-tests/attributes/cancelafter.html": {
29982998
"href": "articles/nunit/writing-tests/attributes/cancelafter.html",
29992999
"title": "CancelAfter | NUnit Docs",
3000-
"summary": "CancelAfter Normally, NUnit simply runs tests and waits for them to terminate -- the test is allowed to run indefinitely. For certain kinds of tests, however, it may be desirable to specify a timeout value. For .NET Core and later, Thread.Abort as used by the TimeoutAttribute can no longer be used, and there is therefore no way to interrupt an endless loop. For all tests, one could use the --blame-hang(-timeout) options of dotnet test. However, this will stop any further execution of the remaining tests. To still be able to cancel tests, one has to move to cooperative cancellation. See Cancellation in Managed Threads using a `CancellationToken``. The CancelAfterAttribute is used to specify a timeout value in milliseconds for a test case. If the test case runs longer than the time specified, the supplied CancellationToken is set to canceled. It is however up to the test code to check this token, either directly or indirectly. The specified timeout value covers the test setup and teardown as well as the test method itself. Before and after actions may also be included, depending on where they were specified. Since the timeout may occur during any of these execution phases, no guarantees can be made as to what will be run and any of these phases of execution may be incomplete. If only used on a test, once a test has timed out, its teardown methods are executed. The attribute may also be specified on a fixture, in which case it indicates the default timeout for any subordinate test cases. When using the console runner, it is also possible to specify a default timeout on the command-line. When used on test methods, NUnit automatically adds an extra argument to your method containing the NUnit CancellationToken. If you want to check for cancellation in SetUp methods, you can use TestContext.CurrentContext.CancellationToken Example The CancelAfterAttribute supports cancellation across a variety of ways to write tests. A simple test, written using the Test attribute: [Test, CancelAfter(2_000)] public void RunningTestUntilCanceled(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { /* */ } } A parameterized test written using the TestCase attribute: [CancelAfter(2000)] [TestCase(\"http://server1\")] [TestCase(\"http://server2\")] public async Task PotentiallyLongRunningTest(string uri, CancellationToken token) { HttpClient client = _httpClientFactory.CreateClient(); HttpContent content = CreateContent(); await client.PostAync(uri, content, token); HttpResponseMessage response = await client.GetAsync(uri, token); /* */ } A parameterized test written using the TestCaseSource attribute: private static int[] _simpleValues = { 2, 4, 6, 8 }; [TestCaseSource(nameof(_simpleValues)), CancelAfter(1_000)] public void TestCaseSourceWithCancellationToken(int a, CancellationToken cancellationToken) { Assert.That(cancellationToken, Is.Not.Default); while (!cancellationToken.IsCancellationRequested) { /* */ } } Note When debugging a unit test, i.e. when a debugger is attached to the process, the timeout is not enforced. See Also Timeout Attribute MaxTime Attribute"
3000+
"summary": "CancelAfter Normally, NUnit simply runs tests and waits for them to terminate -- the test is allowed to run indefinitely. For certain kinds of tests, however, it may be desirable to specify a timeout value. For .NET Core and later, Thread.Abort as used by the TimeoutAttribute can no longer be used, and there is therefore no way to interrupt an endless loop. For all tests, one could use the --blame-hang(-timeout) options of dotnet test. However, this will stop any further execution of the remaining tests. To still be able to cancel tests, one has to move to cooperative cancellation. See Cancellation in Managed Threads using a `CancellationToken``. The CancelAfterAttribute is used to specify a timeout value in milliseconds for a test case. If the test case runs longer than the time specified, the supplied CancellationToken is set to canceled. It is however up to the test code to check this token, either directly or indirectly. The specified timeout value covers the test setup and teardown as well as the test method itself. Before and after actions may also be included, depending on where they were specified. Since the timeout may occur during any of these execution phases, no guarantees can be made as to what will be run and any of these phases of execution may be incomplete. If only used on a test, once a test has timed out, its teardown methods are executed. NUnit will ensure that the cancellation token will be available across all these phases. This also means that the token will be in the \"cancelled\" state in one phase (ex: TearDown) if it were marked as cancelled during a previous phase. It therefore should be used with caution in TearDown phases when getting passed down to other methods which perform cleanup as an already-cancelled token may prevent HTTP or DB calls from being performed. The attribute may also be specified on a fixture, in which case it indicates the default timeout for any subordinate test cases. When using the console runner, it is also possible to specify a default timeout on the command-line. When used on test methods, NUnit automatically adds an extra argument to your method containing the NUnit CancellationToken. If you want to check for cancellation in SetUp methods, you can use TestContext.CurrentContext.CancellationToken Example The CancelAfterAttribute supports cancellation across a variety of ways to write tests. A simple test, written using the Test attribute: [Test, CancelAfter(2_000)] public void RunningTestUntilCanceled(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { /* */ } } A parameterized test written using the TestCase attribute: [CancelAfter(2000)] [TestCase(\"http://server1\")] [TestCase(\"http://server2\")] public async Task PotentiallyLongRunningTest(string uri, CancellationToken token) { HttpClient client = _httpClientFactory.CreateClient(); HttpContent content = CreateContent(); await client.PostAync(uri, content, token); HttpResponseMessage response = await client.GetAsync(uri, token); /* */ } A parameterized test written using the TestCaseSource attribute: private static int[] _simpleValues = { 2, 4, 6, 8 }; [TestCaseSource(nameof(_simpleValues)), CancelAfter(1_000)] public void TestCaseSourceWithCancellationToken(int a, CancellationToken cancellationToken) { Assert.That(cancellationToken, Is.Not.Default); while (!cancellationToken.IsCancellationRequested) { /* */ } } Note When debugging a unit test, i.e. when a debugger is attached to the process, the timeout is not enforced. See Also Timeout Attribute MaxTime Attribute"
30013001
},
30023002
"articles/nunit/writing-tests/attributes/category.html": {
30033003
"href": "articles/nunit/writing-tests/attributes/category.html",

0 commit comments

Comments
 (0)