From ac5f0bddb474283e2412dc039f867ba01761b242 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Oct 2026 00:22:44 +0000 Subject: [PATCH 1/5] Initial plan From 03b227e099f215a4c104348b374b840797fbfe03 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Oct 2026 00:26:04 +0000 Subject: [PATCH 2/5] Document partitioning large NUnit test suites Co-authored-by: stevenaw <439844+stevenaw@users.noreply.github.com> --- .../nunit/writing-tests/partitioning-tests.md | 51 +++++++++++++++++++ docs/articles/nunit/writing-tests/toc.yml | 2 + 2 files changed, 53 insertions(+) create mode 100644 docs/articles/nunit/writing-tests/partitioning-tests.md diff --git a/docs/articles/nunit/writing-tests/partitioning-tests.md b/docs/articles/nunit/writing-tests/partitioning-tests.md new file mode 100644 index 000000000..b3b3b2f3c --- /dev/null +++ b/docs/articles/nunit/writing-tests/partitioning-tests.md @@ -0,0 +1,51 @@ +--- +uid: partitioningtests +--- + +# Partitioning Tests + +When a test suite is too large to run as one job, split it into numbered partitions and run each partition separately. +NUnit assigns each test to a partition, so the jobs together cover the suite without selecting tests by hand. + +## Selecting a partition + +Use the `partition` property in a Test Selection Language expression. The value has the form `PARTITION/TOTAL`: + +```shell +# Run partition 2 of 5 +nunit3-console MyTests.dll --where "partition == 2/5" + +# Or, with dotnet test and an NUnit adapter that supports partition filters +dotnet test -- NUnit.Where="partition == 2/5" +``` + +Partition numbers start at **1**, not 0. To run the whole suite, start one job for each partition from `1` to the same +total. For five jobs, use `1/5`, `2/5`, `3/5`, `4/5` and `5/5`. Keep the total the same for every job. + +NUnit uses a hash of each test's full name to assign it to a partition. This makes assignment repeatable for a given +suite, but does not balance partitions by test duration. Renaming tests can also change their assignments. + +## Keeping fixtures together + +By default, NUnit partitions individual test cases. Tests from one fixture can therefore run in different jobs, with +fixture setup and teardown occurring in more than one job. + +To keep each fixture together, add `:fixture` to the partition value: + +```shell +nunit3-console MyTests.dll --where "partition == 2/5:fixture" +dotnet test -- NUnit.Where="partition == 2/5:fixture" +``` + +Fixture partitioning assigns a fixture as a unit. It may result in less even runtimes when fixtures differ in size. +Explicitly specifying `:test` selects the default test-case partitioning mode. + +## Things to keep in mind + +- Run every partition with the same test assembly and partition count. Changing the total can assign tests to different + partitions. +- Use a runner that supports partition filters. For `dotnet test`, this requires a compatible NUnit adapter. +- Test dependencies may cause a dependent test or fixture to be included in more than one partition. See + [Tests That Depend on Other Tests](xref:dependenttests) for details. + +See the [Test Selection Language](xref:testselectionlanguage) for more about filter expressions. diff --git a/docs/articles/nunit/writing-tests/toc.yml b/docs/articles/nunit/writing-tests/toc.yml index ecb896df6..7264d9b67 100644 --- a/docs/articles/nunit/writing-tests/toc.yml +++ b/docs/articles/nunit/writing-tests/toc.yml @@ -12,6 +12,8 @@ href: flaky-and-slow-tests.md - name: Organizing and Selecting Tests href: organizing-tests.md +- name: Partitioning Tests + href: partitioning-tests.md - name: Attributes href: attributes.md - name: Attribute Descriptions From fe5089853cf31ddb3a7793b0ef0bfbaeea320980 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Oct 2026 00:30:37 +0000 Subject: [PATCH 3/5] Move partitioning guide to running tests Co-authored-by: stevenaw <439844+stevenaw@users.noreply.github.com> --- docs/articles/nunit/running-tests/Console-Command-Line.md | 2 +- docs/articles/nunit/running-tests/NUnitLite-Options.md | 2 +- .../Partitioning-Tests.md} | 0 docs/articles/nunit/running-tests/toc.yml | 4 +++- docs/articles/nunit/writing-tests/toc.yml | 2 -- 5 files changed, 5 insertions(+), 5 deletions(-) rename docs/articles/nunit/{writing-tests/partitioning-tests.md => running-tests/Partitioning-Tests.md} (100%) diff --git a/docs/articles/nunit/running-tests/Console-Command-Line.md b/docs/articles/nunit/running-tests/Console-Command-Line.md index 30de1c3d4..e7a372e21 100644 --- a/docs/articles/nunit/running-tests/Console-Command-Line.md +++ b/docs/articles/nunit/running-tests/Console-Command-Line.md @@ -32,7 +32,7 @@ beginning with 2.0. Without the V2 driver, only version 3.0 and higher tests may |`@FILE` | Specifies the name (or path) of a FILE containing additional command-line arguments to be inserted at the point where the @FILE expression appears. Each line in the file represents one argument to the console runner. If an option takes a value, that value must appear on the same line.| |`--test=FULLNAMES` | Comma-separated list of FULLNAMES of tests to run or explore. This option may be repeated. Note that this option is retained for backward compatibility. The --where option can now be used instead. | |`--testlist=FILE` | The name (or path) of a FILE containing a list of tests to run or explore, one per line. May also include comment lines, indicated by `#` in the first column. | -|`--where=EXPRESSION` | An expression indicating which tests to run. It may specify test names, classes, methods, categories or properties comparing them to actual values with the operators ==, !=, =~ and !~. See [Test Selection Language](Test-Selection-Language.md) for a full description of the syntax. | +|`--where=EXPRESSION` | An expression indicating which tests to run. It may specify test names, classes, methods, categories or properties comparing them to actual values with the operators ==, !=, =~ and !~. Use `partition == NUMBER/TOTAL` to select a numbered partition, or add `:fixture` to keep each fixture together. See [Partitioning Tests](xref:partitioningtests) and [Test Selection Language](Test-Selection-Language.md) for details. | |`--testparam:PARAMETER, --tp:PARAMETER` | A test PARAMETER specified in the form NAME=VALUE for consumption by tests. Multiple parameters must be specified separated using a `--testparam` or `--tp` option for each. | |`--params=PARAMETER, --p=PARAMETER` | (**NOTE:** _this is deprecated and will be removed in a future release. Please use --testparam instead_.) A test PARAMETER specified in the form NAME=VALUE for consumption by tests. Multiple parameters may be specified, separated by semicolons or by repeating the --params option multiple times. Case-sensitive. | |`--config=NAME` | NAME of a project configuration to load (e.g.: Debug). | diff --git a/docs/articles/nunit/running-tests/NUnitLite-Options.md b/docs/articles/nunit/running-tests/NUnitLite-Options.md index 5cf2017fa..0ceb58c36 100644 --- a/docs/articles/nunit/running-tests/NUnitLite-Options.md +++ b/docs/articles/nunit/running-tests/NUnitLite-Options.md @@ -7,7 +7,7 @@ The NUnitLite runner is invoked by executing the test program. If desired, any o | `--test=NAMES` | Comma-separated list of NAMES of tests to run or explore. This option may be repeated. | | `--testlist=PATH` | File PATH containing a list of tests to run, one per line. This option may be repeated. | | `--prefilter=NAMES` | Comma-separated list of NAMES of test classes or namespaces to be loaded. This option may be repeated. | -| `--where=EXPRESSION` | Test selection EXPRESSION indicating what tests will be run. | +| `--where=EXPRESSION` | Test selection EXPRESSION indicating what tests will be run. Use `partition == NUMBER/TOTAL` to select a numbered partition, or add `:fixture` to keep each fixture together. See [Partitioning Tests](xref:partitioningtests) for details. | | `--params, -p=VALUE` | Define a test parameter. | | `--timeout=MILLISECONDS` | Set timeout for each test case in MILLISECONDS. | | `--seed=SEED` | Set the random SEED used to generate test cases. | diff --git a/docs/articles/nunit/writing-tests/partitioning-tests.md b/docs/articles/nunit/running-tests/Partitioning-Tests.md similarity index 100% rename from docs/articles/nunit/writing-tests/partitioning-tests.md rename to docs/articles/nunit/running-tests/Partitioning-Tests.md diff --git a/docs/articles/nunit/running-tests/toc.yml b/docs/articles/nunit/running-tests/toc.yml index c72f910d4..6de59452f 100644 --- a/docs/articles/nunit/running-tests/toc.yml +++ b/docs/articles/nunit/running-tests/toc.yml @@ -11,4 +11,6 @@ - name: Template Based Test Naming href: Template-Based-Test-Naming.md - name: Test Selection Language - href: Test-Selection-Language.md \ No newline at end of file + href: Test-Selection-Language.md +- name: Partitioning Tests + href: Partitioning-Tests.md \ No newline at end of file diff --git a/docs/articles/nunit/writing-tests/toc.yml b/docs/articles/nunit/writing-tests/toc.yml index 7264d9b67..ecb896df6 100644 --- a/docs/articles/nunit/writing-tests/toc.yml +++ b/docs/articles/nunit/writing-tests/toc.yml @@ -12,8 +12,6 @@ href: flaky-and-slow-tests.md - name: Organizing and Selecting Tests href: organizing-tests.md -- name: Partitioning Tests - href: partitioning-tests.md - name: Attributes href: attributes.md - name: Attribute Descriptions From 75a7a048e9def927df6b16e449b605e07d2b0df1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Oct 2026 00:40:00 +0000 Subject: [PATCH 4/5] Document partition filter support versions Co-authored-by: stevenaw <439844+stevenaw@users.noreply.github.com> --- .../nunit/running-tests/Console-Command-Line.md | 2 +- docs/articles/nunit/running-tests/NUnitLite-Options.md | 2 +- .../articles/nunit/running-tests/Partitioning-Tests.md | 2 ++ .../nunit/running-tests/Test-Selection-Language.md | 10 ++++++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/articles/nunit/running-tests/Console-Command-Line.md b/docs/articles/nunit/running-tests/Console-Command-Line.md index e7a372e21..30de1c3d4 100644 --- a/docs/articles/nunit/running-tests/Console-Command-Line.md +++ b/docs/articles/nunit/running-tests/Console-Command-Line.md @@ -32,7 +32,7 @@ beginning with 2.0. Without the V2 driver, only version 3.0 and higher tests may |`@FILE` | Specifies the name (or path) of a FILE containing additional command-line arguments to be inserted at the point where the @FILE expression appears. Each line in the file represents one argument to the console runner. If an option takes a value, that value must appear on the same line.| |`--test=FULLNAMES` | Comma-separated list of FULLNAMES of tests to run or explore. This option may be repeated. Note that this option is retained for backward compatibility. The --where option can now be used instead. | |`--testlist=FILE` | The name (or path) of a FILE containing a list of tests to run or explore, one per line. May also include comment lines, indicated by `#` in the first column. | -|`--where=EXPRESSION` | An expression indicating which tests to run. It may specify test names, classes, methods, categories or properties comparing them to actual values with the operators ==, !=, =~ and !~. Use `partition == NUMBER/TOTAL` to select a numbered partition, or add `:fixture` to keep each fixture together. See [Partitioning Tests](xref:partitioningtests) and [Test Selection Language](Test-Selection-Language.md) for details. | +|`--where=EXPRESSION` | An expression indicating which tests to run. It may specify test names, classes, methods, categories or properties comparing them to actual values with the operators ==, !=, =~ and !~. See [Test Selection Language](Test-Selection-Language.md) for a full description of the syntax. | |`--testparam:PARAMETER, --tp:PARAMETER` | A test PARAMETER specified in the form NAME=VALUE for consumption by tests. Multiple parameters must be specified separated using a `--testparam` or `--tp` option for each. | |`--params=PARAMETER, --p=PARAMETER` | (**NOTE:** _this is deprecated and will be removed in a future release. Please use --testparam instead_.) A test PARAMETER specified in the form NAME=VALUE for consumption by tests. Multiple parameters may be specified, separated by semicolons or by repeating the --params option multiple times. Case-sensitive. | |`--config=NAME` | NAME of a project configuration to load (e.g.: Debug). | diff --git a/docs/articles/nunit/running-tests/NUnitLite-Options.md b/docs/articles/nunit/running-tests/NUnitLite-Options.md index 0ceb58c36..a30b76eb7 100644 --- a/docs/articles/nunit/running-tests/NUnitLite-Options.md +++ b/docs/articles/nunit/running-tests/NUnitLite-Options.md @@ -7,7 +7,7 @@ The NUnitLite runner is invoked by executing the test program. If desired, any o | `--test=NAMES` | Comma-separated list of NAMES of tests to run or explore. This option may be repeated. | | `--testlist=PATH` | File PATH containing a list of tests to run, one per line. This option may be repeated. | | `--prefilter=NAMES` | Comma-separated list of NAMES of test classes or namespaces to be loaded. This option may be repeated. | -| `--where=EXPRESSION` | Test selection EXPRESSION indicating what tests will be run. Use `partition == NUMBER/TOTAL` to select a numbered partition, or add `:fixture` to keep each fixture together. See [Partitioning Tests](xref:partitioningtests) for details. | +| `--where=EXPRESSION` | Test selection EXPRESSION indicating what tests will be run. See [Test Selection Language](Test-Selection-Language.md) for details, including partition filters. | | `--params, -p=VALUE` | Define a test parameter. | | `--timeout=MILLISECONDS` | Set timeout for each test case in MILLISECONDS. | | `--seed=SEED` | Set the random SEED used to generate test cases. | diff --git a/docs/articles/nunit/running-tests/Partitioning-Tests.md b/docs/articles/nunit/running-tests/Partitioning-Tests.md index b3b3b2f3c..61bcb1ab0 100644 --- a/docs/articles/nunit/running-tests/Partitioning-Tests.md +++ b/docs/articles/nunit/running-tests/Partitioning-Tests.md @@ -42,6 +42,8 @@ Explicitly specifying `:test` selects the default test-case partitioning mode. ## Things to keep in mind +- Partition filters require NUnit 3.14 or later; fixture partitioning requires NUnit 5.1 or later. The Console Runner + supports partitions from 3.17, and NUnit3TestAdapter supports them from 4.6. - Run every partition with the same test assembly and partition count. Changing the total can assign tests to different partitions. - Use a runner that supports partition filters. For `dotnet test`, this requires a compatible NUnit adapter. diff --git a/docs/articles/nunit/running-tests/Test-Selection-Language.md b/docs/articles/nunit/running-tests/Test-Selection-Language.md index f50dffdf1..573d32c12 100644 --- a/docs/articles/nunit/running-tests/Test-Selection-Language.md +++ b/docs/articles/nunit/running-tests/Test-Selection-Language.md @@ -44,6 +44,7 @@ The following key words are recognized on the left-hand side of the comparison: * `namespace` - The fully qualified name of the namespace containing the test(s), e.g. My.Name.Space * `method` - The name of the method, e.g. TestMethod * `cat` - A category assigned to the test, e.g. SmokeTests +* `partition` - A numbered partition of the test suite; see [Partitioning Tests](xref:partitioningtests) If the left-hand side of the comparison does not consist of a key word, it is treated as the name of a property on the test whose value is to be checked. See below for restrictions on use of properties. @@ -69,6 +70,15 @@ all do the same thing: test=~TestCaseAttributeTest ``` +## Partitioning Tests + +Use the `partition` keyword with a value of `PARTITION/TOTAL` to select one numbered partition. Partition numbers start +at 1. For example, `partition == 2/5` selects partition 2 of 5. Add `:fixture` to the value to keep each fixture's tests +together, as in `partition == 2/5:fixture`. Without a suffix, the filter partitions individual test cases. + +Partition filters were added in NUnit 3.14. Fixture partitioning was added in NUnit 5.1. Support for partition filters +was added to the NUnit Console Runner in 3.17 and to NUnit3TestAdapter (including `dotnet test`) in 4.6. + For matching regular expressions, NUnit uses .NET's `Regex.IsMatch` method. For detailed information on the syntax of regular expressions in .NET, see [Regular Expressions in .NET](https://docs.microsoft.com/dotnet/standard/base-types/regular-expression-language-quick-reference). From 505038265ebd8f3b1db3445a7d9adad0a12bbb33 Mon Sep 17 00:00:00 2001 From: Steven Weerdenburg Date: Fri, 9 Oct 2026 00:58:12 +0000 Subject: [PATCH 5/5] Manual modifications --- .../nunit/running-tests/NUnitLite-Options.md | 2 +- .../running-tests/Test-Selection-Language.md | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/articles/nunit/running-tests/NUnitLite-Options.md b/docs/articles/nunit/running-tests/NUnitLite-Options.md index a30b76eb7..bc521e364 100644 --- a/docs/articles/nunit/running-tests/NUnitLite-Options.md +++ b/docs/articles/nunit/running-tests/NUnitLite-Options.md @@ -7,7 +7,7 @@ The NUnitLite runner is invoked by executing the test program. If desired, any o | `--test=NAMES` | Comma-separated list of NAMES of tests to run or explore. This option may be repeated. | | `--testlist=PATH` | File PATH containing a list of tests to run, one per line. This option may be repeated. | | `--prefilter=NAMES` | Comma-separated list of NAMES of test classes or namespaces to be loaded. This option may be repeated. | -| `--where=EXPRESSION` | Test selection EXPRESSION indicating what tests will be run. See [Test Selection Language](Test-Selection-Language.md) for details, including partition filters. | +| `--where=EXPRESSION` | Test selection EXPRESSION indicating what tests will be run. See [Test Selection Language](Test-Selection-Language.md) for details. | | `--params, -p=VALUE` | Define a test parameter. | | `--timeout=MILLISECONDS` | Set timeout for each test case in MILLISECONDS. | | `--seed=SEED` | Set the random SEED used to generate test cases. | diff --git a/docs/articles/nunit/running-tests/Test-Selection-Language.md b/docs/articles/nunit/running-tests/Test-Selection-Language.md index 573d32c12..500a18fe4 100644 --- a/docs/articles/nunit/running-tests/Test-Selection-Language.md +++ b/docs/articles/nunit/running-tests/Test-Selection-Language.md @@ -70,15 +70,6 @@ all do the same thing: test=~TestCaseAttributeTest ``` -## Partitioning Tests - -Use the `partition` keyword with a value of `PARTITION/TOTAL` to select one numbered partition. Partition numbers start -at 1. For example, `partition == 2/5` selects partition 2 of 5. Add `:fixture` to the value to keep each fixture's tests -together, as in `partition == 2/5:fixture`. Without a suffix, the filter partitions individual test cases. - -Partition filters were added in NUnit 3.14. Fixture partitioning was added in NUnit 5.1. Support for partition filters -was added to the NUnit Console Runner in 3.17 and to NUnit3TestAdapter (including `dotnet test`) in 4.6. - For matching regular expressions, NUnit uses .NET's `Regex.IsMatch` method. For detailed information on the syntax of regular expressions in .NET, see [Regular Expressions in .NET](https://docs.microsoft.com/dotnet/standard/base-types/regular-expression-language-quick-reference). @@ -127,6 +118,15 @@ cached the ids, not for general use by users. The reason for this restriction is the id that will be assigned to a test. The id is not persistent across test runs and its format can differ between different framework drivers. +## Partitioning Tests + +Use the `partition` keyword with a value of `PARTITION/TOTAL` to select one numbered partition. Partition numbers start +at 1. For example, `partition == 2/5` selects partition 2 of 5. Add `:fixture` to the value to keep each fixture's tests +together, as in `partition == 2/5:fixture`. Without a suffix, the filter partitions individual test cases. + +Partition filters were added in NUnit 3.14. Fixture partitioning was added in NUnit 5.1. Support for partition filters +was added to the NUnit Console Runner in 3.17 and to NUnit3TestAdapter (including `dotnet test`) in 4.6. + ## Compound Expressions Simple expressions may be combined using logical and, logical or, parentheses or negation operators.