diff --git a/docs/articles/nunit/writing-tests/attributes/testcasesource.md b/docs/articles/nunit/writing-tests/attributes/testcasesource.md index 11c3b562e..4043d86d3 100644 --- a/docs/articles/nunit/writing-tests/attributes/testcasesource.md +++ b/docs/articles/nunit/writing-tests/attributes/testcasesource.md @@ -184,6 +184,23 @@ 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)] + +> [!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 @@ -192,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 65def1b32..bc8800d1b 100644 --- a/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs +++ b/docs/snippets/Snippets.NUnit/TestCaseSourceExamples.cs @@ -220,6 +220,60 @@ 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 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; + + cancellationToken.ThrowIfCancellationRequested(); + 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