From 5c488e542b62cccd4754e300916b13206791867f Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Thu, 22 Oct 2026 08:34:26 -0400 Subject: [PATCH 1/3] Document params array support with TestCaseSource Optional parameters and `CancellationToken` injection with `TestCaseSource` were already documented, but `params` arrays (the third feature from nunit/nunit#5057, released in 4.5) were not. Adds a short "Params arrays" section explaining how extra source arguments are gathered into the array, what happens with no extra arguments, and that an array of the right type as the last argument is passed through. Backed by a new tested snippet with all four cases. Fixes #1095 Co-Authored-By: Claude Fable 5.1 --- .../attributes/testcasesource.md | 9 ++++++ .../Snippets.NUnit/TestCaseSourceExamples.cs | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/docs/articles/nunit/writing-tests/attributes/testcasesource.md b/docs/articles/nunit/writing-tests/attributes/testcasesource.md index 11c3b562e..b11823080 100644 --- a/docs/articles/nunit/writing-tests/attributes/testcasesource.md +++ b/docs/articles/nunit/writing-tests/attributes/testcasesource.md @@ -184,6 +184,15 @@ test case data. [!code-csharp[OptionalParameters](~/snippets/Snippets.NUnit/TestCaseSourceExamples.cs#OptionalParameters)] +### Params arrays + +When the last parameter of the test method is a `params` array, any arguments supplied by the source beyond the fixed +parameters are gathered into that array, just as they are for [TestCase](xref:attribute-testcase). A test case that +supplies no extra arguments gives an empty array, and a test case whose last argument is already an array of the right +type passes it through unchanged. (_NUnit 4.5+_) + +[!code-csharp[ParamsArray](~/snippets/Snippets.NUnit/TestCaseSourceExamples.cs#ParamsArray)] + ### CancellationToken support When using `[CancelAfter]` with `TestCaseSource`, NUnit automatically injects a `CancellationToken` as the last diff --git a/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs b/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs index 65def1b32..dc4258890 100644 --- a/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs +++ b/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs @@ -220,6 +220,35 @@ private static IEnumerable OptionalParameterCases() } #endregion + #region ParamsArray + [TestFixture] + public class ParamsArrayFixture + { + [TestCaseSource(nameof(ParamsArrayCases))] + public void TestWithParamsArray(string name, params int[] values) + { + Assert.That(name, Is.Not.Null); + Assert.That(values, Is.Not.Null); + Assert.That(values, Is.All.Positive); + } + + private static IEnumerable ParamsArrayCases() + { + // Extra arguments are gathered into the params array: values = [1, 2, 3] + yield return new TestCaseData("three", 1, 2, 3); + + // A single extra argument gives a one-element array: values = [1] + yield return new TestCaseData("one", 1); + + // No extra arguments gives an empty array: values = [] + yield return new TestCaseData("none"); + + // An array of the right type as the last argument is used as-is: values = [4, 5] + yield return new TestCaseData("array", new[] { 4, 5 }); + } + } + #endregion + #region CancellationTokenSupport [TestFixture] public class CancellationTokenFixture From deb8431d5e8e69c288c32ccc0b2a5311579372cc Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Thu, 22 Oct 2026 21:19:49 -0400 Subject: [PATCH 2/3] Note that params arrays cannot be combined with CancellationToken injection A params array must be the last parameter, so a test method cannot also declare the CancellationToken parameter that [CancelAfter] injects. Add a note to the Params arrays section and a cross-reference in the CancellationToken section pointing to TestContext.CurrentContext.CancellationToken as the alternative, backed by a tested snippet. Addresses review feedback from @manfred-brands. Co-Authored-By: Claude Fable 5.1 --- .../attributes/testcasesource.md | 11 ++++++++ .../Snippets.NUnit/TestCaseSourceExamples.cs | 25 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/docs/articles/nunit/writing-tests/attributes/testcasesource.md b/docs/articles/nunit/writing-tests/attributes/testcasesource.md index b11823080..4043d86d3 100644 --- a/docs/articles/nunit/writing-tests/attributes/testcasesource.md +++ b/docs/articles/nunit/writing-tests/attributes/testcasesource.md @@ -193,6 +193,14 @@ type passes it through unchanged. (_NUnit 4.5+_) [!code-csharp[ParamsArray](~/snippets/Snippets.NUnit/TestCaseSourceExamples.cs#ParamsArray)] +> [!NOTE] +> A `params` array must be the last parameter of the method, so a test that uses one cannot also declare the +> `CancellationToken` parameter that [CancelAfter](xref:attribute-cancelafter) injects (see +> [CancellationToken support](#cancellationtoken-support) below). When combining `[CancelAfter]` with a `params` +> array, read the token from `TestContext.CurrentContext.CancellationToken` instead. + +[!code-csharp[ParamsArrayWithCancelAfter](~/snippets/Snippets.NUnit/TestCaseSourceExamples.cs#ParamsArrayWithCancelAfter)] + ### CancellationToken support When using `[CancelAfter]` with `TestCaseSource`, NUnit automatically injects a `CancellationToken` as the last @@ -201,6 +209,9 @@ provides it automatically. [!code-csharp[CancellationTokenSupport](~/snippets/Snippets.NUnit/TestCaseSourceExamples.cs#CancellationTokenSupport)] +Because the injected `CancellationToken` must be the last parameter, this cannot be combined with a +[`params` array](#params-arrays). In that case, use `TestContext.CurrentContext.CancellationToken` instead. + See [CancelAfter](xref:attribute-cancelafter) for more information on cancellation token handling. ## Test Case Construction diff --git a/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs b/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs index dc4258890..471a36ace 100644 --- a/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs +++ b/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs @@ -249,6 +249,31 @@ private static IEnumerable ParamsArrayCases() } #endregion + #region ParamsArrayWithCancelAfter + [TestFixture] + public class ParamsArrayWithCancelAfterFixture + { + [TestCaseSource(nameof(Cases))] + [CancelAfter(5000)] + public void TestWithParamsArrayAndCancelAfter(string name, params int[] values) + { + // A CancellationToken parameter cannot follow a params array, + // so read the token from the test context instead. + CancellationToken cancellationToken = TestContext.CurrentContext.CancellationToken; + + Assert.That(cancellationToken, Is.Not.EqualTo(default(CancellationToken))); + Assert.That(name, Is.Not.Null); + Assert.That(values, Is.All.Positive); + } + + private static IEnumerable Cases() + { + yield return new TestCaseData("three", 1, 2, 3); + yield return new TestCaseData("none"); + } + } + #endregion + #region CancellationTokenSupport [TestFixture] public class CancellationTokenFixture From f742acfdec6dd215841b5ad4a6baab558acd02bb Mon Sep 17 00:00:00 2001 From: Sean Killeen Date: Fri, 23 Oct 2026 08:36:59 -0400 Subject: [PATCH 3/3] Update docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs Co-authored-by: Manfred Brands --- docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs b/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs index 471a36ace..bc8800d1b 100644 --- a/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs +++ b/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs @@ -261,7 +261,7 @@ public void TestWithParamsArrayAndCancelAfter(string name, params int[] values) // so read the token from the test context instead. CancellationToken cancellationToken = TestContext.CurrentContext.CancellationToken; - Assert.That(cancellationToken, Is.Not.EqualTo(default(CancellationToken))); + cancellationToken.ThrowIfCancellationRequested(); Assert.That(name, Is.Not.Null); Assert.That(values, Is.All.Positive); }