From 56d913f6d09f0575bdf9cabca8acfc0d8fb1c133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 16 Feb 2026 14:09:59 +0100 Subject: [PATCH 1/2] Fix MSTest docs Address review comments post merge --- ...est-writing-tests-controlling-execution.md | 2 +- ...esting-mstest-writing-tests-data-driven.md | 44 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-controlling-execution.md b/docs/core/testing/unit-testing-mstest-writing-tests-controlling-execution.md index 6f514585ecbd2..0bf2091fc2d0f 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-controlling-execution.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-controlling-execution.md @@ -145,7 +145,7 @@ The `Workers` property specifies the maximum number of threads for parallel exec > You can also configure parallelization through [runsettings](unit-testing-mstest-configure.md#mstest-element) or [testconfig.json](unit-testing-mstest-configure.md#testconfigjson) without modifying code. > [!TIP] -> Enable parallelization at the assembly level by default, even if many tests currently require sequential execution. This approach encourages writing new tests that support parallel execution from the start. Use the [MSTEST0001](mstest-analyzers/mstest0001.md) analyzer to ensure that every test class explicitly declares its parallelization intent, which forces you to review whether each class safely supports concurrent execution. Often, excluding just a few classes or methods with `DoNotParallelize` is sufficient, allowing the majority of your tests to run in parallel for significantly faster test execution. +> Enable parallelization at the assembly level by default, even if many tests currently require sequential execution. This approach encourages writing new tests that support parallel execution from the start. Use the [MSTEST0001](mstest-analyzers/mstest0001.md) analyzer to ensure that the assembly explicitly declares its parallelization intent with `[assembly: Parallelize]` or `[assembly: DoNotParallelize]`. Once parallelization is enabled, review each test class to determine whether it safely supports concurrent execution. Often, excluding just a few classes or methods with `DoNotParallelize` is sufficient, allowing the majority of your tests to run in parallel for significantly faster test execution. ### `DoNotParallelizeAttribute` diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md b/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md index 86f1ecf209a10..d7149f4daad0c 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md @@ -18,9 +18,12 @@ MSTest provides several attributes for data-driven testing: |-----------|----------|----------| | [`DataRow`](#datarowattribute) | Inline test data | Simple, static test cases | | [`DynamicData`](#dynamicdataattribute) | Data from methods, properties, or fields | Complex or computed test data | -| [`TestDataRow`](#testdatarow) | Enhanced data with metadata | Test cases needing display names or categories | | [`DataSource`](#datasourceattribute) | External data files or databases | Legacy scenarios with external data sources | -| [`ITestDataSource`](#itestdatasource) | Custom data source attributes | Fully custom data-driven scenarios | + +MSTest also provides the following types to extend data-driven scenarios: + +- [`TestDataRow`](#testdatarow): A return type for `DynamicData` sources that adds metadata support such as display names, categories, and ignore messages to individual test cases. +- [`ITestDataSource`](#itestdatasource): An interface you can implement on a custom attribute to create fully custom data source attributes. > [!TIP] > For combinatorial testing (testing all combinations of multiple parameter sets), use the open-source [Combinatorial.MSTest](https://www.nuget.org/packages/Combinatorial.MSTest) NuGet package. This community-maintained package is [available on GitHub](https://github.com/Youssef1313/Combinatorial.MSTest) but isn't maintained by Microsoft. @@ -237,10 +240,10 @@ Specify a different class using the type parameter: ```csharp public class TestDataProvider { - public static IEnumerable GetTestData() + public static IEnumerable<(int, string)> GetTestData() { - yield return new object[] { 1, "first" }; - yield return new object[] { 2, "second" }; + yield return (1, "first"); + yield return (2, "second"); } } @@ -273,10 +276,10 @@ public class DynamicDataDisplayNameExample Assert.IsTrue(value1 > 0); } - public static IEnumerable GetTestData() + public static IEnumerable<(int, string)> GetTestData() { - yield return new object[] { 1, "first" }; - yield return new object[] { 2, "second" }; + yield return (1, "first"); + yield return (2, "second"); } public static string GetDisplayName(MethodInfo methodInfo, object[] data) @@ -307,10 +310,10 @@ public class IgnoreDynamicDataExample // All test cases from GetTestData are skipped } - public static IEnumerable GetTestData() + public static IEnumerable<(int, string)> GetTestData() { - yield return new object[] { 1, "first" }; - yield return new object[] { 2, "second" }; + yield return (1, "first"); + yield return (2, "second"); } } ``` @@ -340,7 +343,7 @@ public class TestDataRowExample Assert.IsTrue(value1 > 0); } - public static IEnumerable GetTestDataRows() + public static IEnumerable> GetTestDataRows() { yield return new TestDataRow((1, "first")) { @@ -511,27 +514,22 @@ For most scenarios, the default `Auto` behavior provides the best balance. Consi public class UnfoldingExample { [TestMethod(UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Unfold)] // That's the default behavior - [DataRow(1)] - [DataRow(2)] - [DataRow(3)] + [DataRow(1, "one")] + [DataRow(2, "two")] + [DataRow(3, "three")] public void TestMethodWithUnfolding(int value, string text) { // Each test case appears individually in Test Explorer } [TestMethod(UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] - [DynamicData(nameof(GetData))] + [DataRow(1, "one")] + [DataRow(2, "two")] + [DataRow(3, "three")] public void TestMethodWithFolding(int value, string text) { // All test cases appear as a single collapsed node } - - public static IEnumerable<(int, string)> GetData() - { - yield return (1, "one"); - yield return (2, "two"); - yield return (3, "three"); - } } ``` From f503b2c868f4cc76401a7fb31fb5e01056e8db66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 16 Feb 2026 21:36:09 +0100 Subject: [PATCH 2/2] Address review comments --- .../unit-testing-mstest-writing-tests-data-driven.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md b/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md index d7149f4daad0c..18d421a4db545 100644 --- a/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md +++ b/docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md @@ -22,7 +22,7 @@ MSTest provides several attributes for data-driven testing: MSTest also provides the following types to extend data-driven scenarios: -- [`TestDataRow`](#testdatarow): A return type for `DynamicData` sources that adds metadata support such as display names, categories, and ignore messages to individual test cases. +- [`TestDataRow`](#testdatarow): A return type for `ITestDataSource` implementations (including `DynamicData`) that adds metadata support such as display names, categories, and ignore messages to individual test cases. - [`ITestDataSource`](#itestdatasource): An interface you can implement on a custom attribute to create fully custom data source attributes. > [!TIP] @@ -345,18 +345,18 @@ public class TestDataRowExample public static IEnumerable> GetTestDataRows() { - yield return new TestDataRow((1, "first")) + yield return new TestDataRow<(int, string)>((1, "first")) { DisplayName = "Test Case 1: Basic scenario", }; - yield return new TestDataRow((2, "second")) + yield return new TestDataRow<(int, string)>((2, "second")) { DisplayName = "Test Case 2: Edge case", TestCategories = ["HighPriority", "Critical"], }; - yield return new TestDataRow((3, "third")) + yield return new TestDataRow<(int, string)>((3, "third")) { IgnoreMessage = "Not yet implemented", };