From cdefc18ab9bafbba42efeb2e5bd0e4ce3d553b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 8 Jul 2026 10:57:00 +0200 Subject: [PATCH 1/4] Let explicit --minimum-expected-tests govern the zero-tests verdict (#7457) In TestApplicationResult.GetProcessExitCode(), an explicitly-provided --minimum-expected-tests now governs the count-based verdict and supersedes the ZeroTests (exit code 8) verdict: a run of fewer than N tests yields MinimumExpectedTestsPolicyViolation (exit code 9) even when zero tests ran. This lets a 'dotnet test --test-modules' orchestrator tell a stricter per-module minimum (forwarded via '-- --minimum-expected-tests N') apart from a module that simply matched no tests, which is the precondition for deciding the 'zero tests ran' verdict at the whole-run level instead of per module. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/Changelog-Platform.md | 1 + .../Services/TestApplicationResult.cs | 28 ++++++++++++------- .../ExecutionTests.cs | 12 ++++++++ .../Services/TestApplicationResultTests.cs | 17 +++++++++++ 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/docs/Changelog-Platform.md b/docs/Changelog-Platform.md index e67c15b364..f366b8e460 100644 --- a/docs/Changelog-Platform.md +++ b/docs/Changelog-Platform.md @@ -48,6 +48,7 @@ See full log [of v4.2.3...v4.3.0](https://github.com/microsoft/testfx/compare/v4 * Re-print errored assemblies in dotnet test end-of-run recap by @Evangelink in [#9545](https://github.com/microsoft/testfx/pull/9545) * Add server-initiated session cancellation to the dotnet test IPC protocol by @Evangelink in [#9549](https://github.com/microsoft/testfx/pull/9549) * Emit `::warning` annotations for skipped tests in `Microsoft.Testing.Extensions.GitHubActionsReport` by @Evangelink in [#9641](https://github.com/microsoft/testfx/pull/9641) +* Let an explicit `--minimum-expected-tests N` govern the zero-tests verdict, so a run of fewer than N tests reports the minimum-expected violation (exit code 9) instead of "zero tests ran" (exit code 8) even when no test ran. This lets a `dotnet test --test-modules` orchestrator tell a stricter local-minimum violation apart from an empty module (#7457) by @Copilot in [#9709](https://github.com/microsoft/testfx/pull/9709) ### Fixed diff --git a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs index 5fe1438183..07b78c69eb 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs @@ -144,20 +144,28 @@ public int GetProcessExitCode() exitCode = exitCode == ExitCode.Success && _failedTestsCount > 0 ? ExitCode.AtLeastOneTestFailed : exitCode; exitCode = exitCode == ExitCode.Success && _policiesService.IsAbortTriggered ? ExitCode.TestSessionAborted : exitCode; - // Determine whether the run should be treated as having executed zero tests. Skipped tests are excluded - // from `_totalRanTests`. Under the default `allow-skipped` policy (#9385) skipped tests count as run, so only - // a run that discovered nothing at all counts as zero tests; under `strict` an all-skipped run also counts - // as zero tests. - ZeroTestsPolicy zeroTestsPolicy = PlatformCommandLineProvider.GetZeroTestsPolicy(_commandLineOptions); - bool ranZeroTests = zeroTestsPolicy == ZeroTestsPolicy.AllowSkipped - ? _totalRanTests == 0 && _skippedTestsCount == 0 - : _totalRanTests == 0; - exitCode = exitCode == ExitCode.Success && ranZeroTests ? ExitCode.ZeroTests : exitCode; - + // An explicitly-provided `--minimum-expected-tests` governs the count-based verdict and + // supersedes the ZeroTests (8) verdict below: a run of fewer than N tests yields + // ExitCode.MinimumExpectedTestsPolicyViolation (9), even when zero tests ran. This lets callers + // tell an explicit-minimum violation apart from a plain "ran nothing" run (e.g. so a + // `dotnet test --test-modules` orchestrator can distinguish a stricter local minimum from an + // empty module). See issue #7457. if (_commandLineOptions.TryGetOptionArgumentList(PlatformCommandLineProvider.MinimumExpectedTestsOptionKey, out string[]? argumentList)) { exitCode = exitCode == ExitCode.Success && _totalRanTests < int.Parse(argumentList[0], CultureInfo.InvariantCulture) ? ExitCode.MinimumExpectedTestsPolicyViolation : exitCode; } + else + { + // Determine whether the run should be treated as having executed zero tests. Skipped tests are excluded + // from `_totalRanTests`. Under the default `allow-skipped` policy (#9385) skipped tests count as run, so only + // a run that discovered nothing at all counts as zero tests; under `strict` an all-skipped run also counts + // as zero tests. + ZeroTestsPolicy zeroTestsPolicy = PlatformCommandLineProvider.GetZeroTestsPolicy(_commandLineOptions); + bool ranZeroTests = zeroTestsPolicy == ZeroTestsPolicy.AllowSkipped + ? _totalRanTests == 0 && _skippedTestsCount == 0 + : _totalRanTests == 0; + exitCode = exitCode == ExitCode.Success && ranZeroTests ? ExitCode.ZeroTests : exitCode; + } // If the user has specified the IgnoreExitCode, then we don't want to return a non-zero exit code if the exit code matches the one specified. string? exitCodeToIgnore = _environment.GetEnvironmentVariable(EnvironmentVariableConstants.TESTINGPLATFORM_EXITCODE_IGNORE); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs index f4755b6142..fe14840d44 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs @@ -172,6 +172,18 @@ public async Task Exec_WhenMinimumExpectedTestsIsNegative_ResultIsNotOk(string t testHostResult.AssertOutputContains("Option '--minimum-expected-tests' has invalid arguments: '--minimum-expected-tests' expects a single non-zero positive integer value"); } + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] + public async Task Exec_WhenMinimumExpectedTestsIsSpecifiedAndNoTestsRun_ResultIsMinimumExpectedTestsPolicyViolation(string tfm) + { + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + // The uid filter matches no test, so zero tests run. With an explicit minimum, the count-based + // verdict is a minimum-expected violation (exit code 9), not "zero tests ran" (exit code 8). See issue #7457. + TestHostResult testHostResult = await testHost.ExecuteAsync("--filter-uid 2 --minimum-expected-tests 3", cancellationToken: TestContext.CancellationToken); + + testHostResult.AssertExitCodeIs(ExitCode.MinimumExpectedTestsPolicyViolation); + } + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] [TestMethod] public async Task Exec_WhenListTestsAndMinimumExpectedTestsAreSpecified_DiscoveryFails(string tfm) diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs index 634fe727a8..4c3637f073 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs @@ -212,6 +212,23 @@ TestApplicationResult testApplicationResult Assert.AreEqual((int)ExitCode.MinimumExpectedTestsPolicyViolation, testApplicationResult.GetProcessExitCode()); } + [TestMethod] + public void GetProcessExitCodeAsync_If_MinimumExpectedTests_Set_And_No_Tests_Ran_Returns_MinimumExpectedTestsPolicyViolation() + { + // When an explicit minimum is set, a zero-test run is reported as a minimum-expected violation (9) + // rather than ZeroTests (8), so an orchestrator can tell a stricter-local-minimum violation apart + // from a plain "ran nothing" module. See issue #7457. + TestApplicationResult testApplicationResult + = new( + new Mock().Object, + new CommandLineOption(PlatformCommandLineProvider.MinimumExpectedTestsOptionKey, ["2"]), + new Mock().Object, + new Mock().Object, + null); + + Assert.AreEqual((int)ExitCode.MinimumExpectedTestsPolicyViolation, testApplicationResult.GetProcessExitCode()); + } + [TestMethod] public async Task GetProcessExitCodeAsync_OnDiscovery_No_Tests_Discovered_Returns_ZeroTests() { From addaa4c0c73c7f375b74db44821d63feb7423a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 8 Jul 2026 13:54:29 +0200 Subject: [PATCH 2/4] Allow --minimum-expected-tests 0 (#7457) (#9724) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/Changelog-Platform.md | 1 + .../PlatformCommandLineProvider.cs | 2 +- .../Resources/PlatformResources.resx | 2 +- .../Resources/xlf/PlatformResources.cs.xlf | 4 ++-- .../Resources/xlf/PlatformResources.de.xlf | 4 ++-- .../Resources/xlf/PlatformResources.es.xlf | 4 ++-- .../Resources/xlf/PlatformResources.fr.xlf | 4 ++-- .../Resources/xlf/PlatformResources.it.xlf | 4 ++-- .../Resources/xlf/PlatformResources.ja.xlf | 4 ++-- .../Resources/xlf/PlatformResources.ko.xlf | 4 ++-- .../Resources/xlf/PlatformResources.pl.xlf | 4 ++-- .../Resources/xlf/PlatformResources.pt-BR.xlf | 4 ++-- .../Resources/xlf/PlatformResources.ru.xlf | 4 ++-- .../Resources/xlf/PlatformResources.tr.xlf | 4 ++-- .../xlf/PlatformResources.zh-Hans.xlf | 4 ++-- .../xlf/PlatformResources.zh-Hant.xlf | 4 ++-- .../ExecutionTests.cs | 14 ++++++++++++- .../PlatformCommandLineProviderTests.cs | 20 +++++++++++++++++-- .../Services/TestApplicationResultTests.cs | 17 ++++++++++++++++ 19 files changed, 77 insertions(+), 31 deletions(-) diff --git a/docs/Changelog-Platform.md b/docs/Changelog-Platform.md index f366b8e460..52f9d3d9d7 100644 --- a/docs/Changelog-Platform.md +++ b/docs/Changelog-Platform.md @@ -49,6 +49,7 @@ See full log [of v4.2.3...v4.3.0](https://github.com/microsoft/testfx/compare/v4 * Add server-initiated session cancellation to the dotnet test IPC protocol by @Evangelink in [#9549](https://github.com/microsoft/testfx/pull/9549) * Emit `::warning` annotations for skipped tests in `Microsoft.Testing.Extensions.GitHubActionsReport` by @Evangelink in [#9641](https://github.com/microsoft/testfx/pull/9641) * Let an explicit `--minimum-expected-tests N` govern the zero-tests verdict, so a run of fewer than N tests reports the minimum-expected violation (exit code 9) instead of "zero tests ran" (exit code 8) even when no test ran. This lets a `dotnet test --test-modules` orchestrator tell a stricter local-minimum violation apart from an empty module (#7457) by @Copilot in [#9709](https://github.com/microsoft/testfx/pull/9709) +* Allow `--minimum-expected-tests 0` so an explicit zero minimum accepts an empty run (same outcome as `--ignore-exit-code 8`), giving a per-module "zero tests is acceptable" opt-in (#7457) by @Copilot in [#9724](https://github.com/microsoft/testfx/pull/9724) ### Fixed diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs index 50879c750c..990c0aa05f 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs @@ -202,7 +202,7 @@ public static bool IsListTestsJsonOutput(ICommandLineOptions commandLineOptions) private static Task IsMinimumExpectedTestsOptionValidAsync(CommandLineOption option, string[] arguments) => option.Name == MinimumExpectedTestsOptionKey - && (arguments.Length != 1 || !int.TryParse(arguments[0], out int value) || value <= 0) + && (arguments.Length != 1 || !int.TryParse(arguments[0], out int value) || value < 0) ? ValidationResult.InvalidTask(PlatformResources.PlatformCommandLineMinimumExpectedTestsOptionSingleArgument) : ValidationResult.ValidTask; diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index eba7e4715e..8b07861e82 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -497,7 +497,7 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print {Locked="--list-tests"}{Locked="--minimum-expected-tests"} - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index a8f18b45e4..25004bf8f1 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -591,9 +591,9 @@ Volitelně přijímá hodnotu „text“ (výchozí výstup čitelný pro člov - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - --minimum-expected-tests očekává jednu kladnou nenulovou celočíselnou hodnotu + --minimum-expected-tests očekává jednu kladnou nenulovou celočíselnou hodnotu (např. --minimum-expected-tests 10). {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 3cc0f98381..0af729de6d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -591,9 +591,9 @@ Akzeptiert optional „text“ (die standardmäsige lesbare Ausgabe) oder „jso - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - "--minimum-expected-tests" erwartet einen einzelnen positiven ganzzahligen Wert ungleich Null + "--minimum-expected-tests" erwartet einen einzelnen positiven ganzzahligen Wert ungleich Null (Beispiel: "--minimum-expected-tests 10") {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 9029a4b074..4f3969a0e3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -591,9 +591,9 @@ Opcionalmente, acepta "text" (la salida legible por el usuario predeterminada) o - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' espera un único valor entero positivo distinto de cero + '--minimum-expected-tests' espera un único valor entero positivo distinto de cero (por ejemplo, '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index c8b87178f9..82b28299df 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -591,9 +591,9 @@ Accepte éventuellement « text » (sortie lisible par l’humain par défaut) - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - « --minimum-expected-tests » attend une seule valeur entière positive différente de zéro + « --minimum-expected-tests » attend une seule valeur entière positive différente de zéro (par exemple, « --minimum-expected-tests 10 ») {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index 0fc26c2e8e..6a31ac096b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -591,9 +591,9 @@ Facoltativamente accetta ''text'' (output leggibile predefinito) o ''json'' per - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' prevede un singolo valore intero positivo diverso da zero + '--minimum-expected-tests' prevede un singolo valore intero positivo diverso da zero (ad esempio '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 7b4ecde384..096084bbc2 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -592,9 +592,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' には、0 以外の正の整数値が 1 つ必要です + '--minimum-expected-tests' には、0 以外の正の整数値が 1 つ必要です (例: '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index b701d8459d..119ea840c9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests'에는 0이 아닌 단일 양의 정수 값이 필요합니다. + '--minimum-expected-tests'에는 0이 아닌 단일 양의 정수 값이 필요합니다. (예: '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 46ba603b81..55e73c3590 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -591,9 +591,9 @@ Opcjonalnie akceptuje „text” (domyślne dane wyjściowe czytelne dla człowi - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - Opcja „--minimum-expected-tests” oczekuje pojedynczej niezerowej dodatniej liczby całkowitej + Opcja „--minimum-expected-tests” oczekuje pojedynczej niezerowej dodatniej liczby całkowitej (np. „--minimum-expected-tests 10”) {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index af0ad62dbd..71a17b8bcb 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -591,9 +591,9 @@ Opcionalmente, aceita 'text' (a saída legível por humanos padrão) ou 'json' p - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' espera um único valor inteiro positivo diferente de zero + '--minimum-expected-tests' espera um único valor inteiro positivo diferente de zero (por exemplo, '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index a424a69ea7..fdb677cb8f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - "--minimum-expected-tests" ожидает единственное ненулевое положительное целое значение + "--minimum-expected-tests" ожидает единственное ненулевое положительное целое значение (например, "--minimum-expected-tests 10") {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 3e1d58a17b..c9bd493775 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests', sıfır olmayan tek bir pozitif tamsayı değeri bekler + '--minimum-expected-tests', sıfır olmayan tek bir pozitif tamsayı değeri bekler (ör. '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 85a8ec4d5f..8d8390deb5 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - "--minimum-expected-tests" 应有单个非零正整数值 + "--minimum-expected-tests" 应有单个非零正整数值 (例如 "--minimum-expected-tests 10") {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 0aea3dfde1..57fb2d842e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-zero positive integer value + '--minimum-expected-tests' expects a single non-negative integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' 需要單一非零的正整數值 + '--minimum-expected-tests' 需要單一非零的正整數值 (例如 '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs index fe14840d44..3da5a4506b 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs @@ -169,7 +169,19 @@ public async Task Exec_WhenMinimumExpectedTestsIsNegative_ResultIsNotOk(string t TestHostResult testHostResult = await testHost.ExecuteAsync("--minimum-expected-tests=-1", cancellationToken: TestContext.CancellationToken); testHostResult.AssertExitCodeIs(ExitCode.InvalidCommandLine); - testHostResult.AssertOutputContains("Option '--minimum-expected-tests' has invalid arguments: '--minimum-expected-tests' expects a single non-zero positive integer value"); + testHostResult.AssertOutputContains("Option '--minimum-expected-tests' has invalid arguments: '--minimum-expected-tests' expects a single non-negative integer value"); + } + + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] + public async Task Exec_WhenMinimumExpectedTestsIsZeroAndNoTestsRun_ResultIsOk(string tfm) + { + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + // The uid filter matches no test, so zero tests run. An explicit '--minimum-expected-tests 0' + // accepts that empty run and supersedes the "zero tests ran" (exit code 8) verdict. See issue #7457. + TestHostResult testHostResult = await testHost.ExecuteAsync("--filter-uid 2 --minimum-expected-tests 0", cancellationToken: TestContext.CancellationToken); + + testHostResult.AssertExitCodeIs(ExitCode.Success); } [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs index f2395774e9..74313e812c 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs @@ -215,9 +215,12 @@ public async Task IsInvalid_When_Both_FilterUid_And_TreenodeFilter_Provided() } [TestMethod] - [DataRow("0")] [DataRow("-1")] - public async Task IsInvalid_When_MinimumExpectedTests_Is_Not_Positive(string minimumExpectedTests) + [DataRow("-5")] + [DataRow("abc")] + [DataRow("")] + [DataRow("1.5")] + public async Task IsInvalid_When_MinimumExpectedTests_Is_Negative_Or_Not_An_Integer(string minimumExpectedTests) { var provider = new PlatformCommandLineProvider(); CommandLineOption option = provider.GetCommandLineOptions().First(x => x.Name == PlatformCommandLineProvider.MinimumExpectedTestsOptionKey); @@ -227,6 +230,19 @@ public async Task IsInvalid_When_MinimumExpectedTests_Is_Not_Positive(string min Assert.AreEqual(PlatformResources.PlatformCommandLineMinimumExpectedTestsOptionSingleArgument, validateOptionsResult.ErrorMessage); } + [TestMethod] + [DataRow("0")] + [DataRow("1")] + [DataRow("10")] + public async Task IsValid_When_MinimumExpectedTests_Is_NonNegative_Integer(string minimumExpectedTests) + { + var provider = new PlatformCommandLineProvider(); + CommandLineOption option = provider.GetCommandLineOptions().First(x => x.Name == PlatformCommandLineProvider.MinimumExpectedTestsOptionKey); + + ValidationResult validateOptionsResult = await provider.ValidateOptionArgumentsAsync(option, [minimumExpectedTests]).ConfigureAwait(false); + Assert.IsTrue(validateOptionsResult.IsValid); + } + [TestMethod] public async Task IsValid_When_DiscoverTests_HasNoArgument() { diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs index 4c3637f073..877c05a783 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs @@ -212,6 +212,23 @@ TestApplicationResult testApplicationResult Assert.AreEqual((int)ExitCode.MinimumExpectedTestsPolicyViolation, testApplicationResult.GetProcessExitCode()); } + [TestMethod] + public void GetProcessExitCodeAsync_If_MinimumExpectedTests_Zero_And_No_Tests_Ran_Returns_Success() + { + // An explicit `--minimum-expected-tests 0` accepts an empty run, superseding the ZeroTests (8) + // verdict. This is how a `dotnet test --test-modules` orchestrator flows "zero is acceptable for + // this module" down to each module. See issue #7457. + TestApplicationResult testApplicationResult + = new( + new Mock().Object, + new CommandLineOption(PlatformCommandLineProvider.MinimumExpectedTestsOptionKey, ["0"]), + new Mock().Object, + new Mock().Object, + null); + + Assert.AreEqual((int)ExitCode.Success, testApplicationResult.GetProcessExitCode()); + } + [TestMethod] public void GetProcessExitCodeAsync_If_MinimumExpectedTests_Set_And_No_Tests_Ran_Returns_MinimumExpectedTestsPolicyViolation() { From d3a1bfcd7b9cab6ed3a7fa00149479f2a2d5f9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 8 Jul 2026 16:21:12 +0200 Subject: [PATCH 3/4] Address review: guard minimum-expected-tests parse; changelog grammar - Defensively guard the --minimum-expected-tests value extraction in TestApplicationResult.GetProcessExitCode() with a single-argument pattern match plus int.TryParse, instead of indexing argumentList[0] and int.Parse (which could throw if the option ever reached here present-but-empty or non-integer). Malformed values now fall back to the zero-tests verdict; they are still rejected earlier by option validation in practice. - Fix changelog grammar: 'no test ran' -> 'no tests ran'. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/Changelog-Platform.md | 2 +- .../Services/TestApplicationResult.cs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/Changelog-Platform.md b/docs/Changelog-Platform.md index 52f9d3d9d7..ad7637332f 100644 --- a/docs/Changelog-Platform.md +++ b/docs/Changelog-Platform.md @@ -48,7 +48,7 @@ See full log [of v4.2.3...v4.3.0](https://github.com/microsoft/testfx/compare/v4 * Re-print errored assemblies in dotnet test end-of-run recap by @Evangelink in [#9545](https://github.com/microsoft/testfx/pull/9545) * Add server-initiated session cancellation to the dotnet test IPC protocol by @Evangelink in [#9549](https://github.com/microsoft/testfx/pull/9549) * Emit `::warning` annotations for skipped tests in `Microsoft.Testing.Extensions.GitHubActionsReport` by @Evangelink in [#9641](https://github.com/microsoft/testfx/pull/9641) -* Let an explicit `--minimum-expected-tests N` govern the zero-tests verdict, so a run of fewer than N tests reports the minimum-expected violation (exit code 9) instead of "zero tests ran" (exit code 8) even when no test ran. This lets a `dotnet test --test-modules` orchestrator tell a stricter local-minimum violation apart from an empty module (#7457) by @Copilot in [#9709](https://github.com/microsoft/testfx/pull/9709) +* Let an explicit `--minimum-expected-tests N` govern the zero-tests verdict, so a run of fewer than N tests reports the minimum-expected violation (exit code 9) instead of "zero tests ran" (exit code 8) even when no tests ran. This lets a `dotnet test --test-modules` orchestrator tell a stricter local-minimum violation apart from an empty module (#7457) by @Copilot in [#9709](https://github.com/microsoft/testfx/pull/9709) * Allow `--minimum-expected-tests 0` so an explicit zero minimum accepts an empty run (same outcome as `--ignore-exit-code 8`), giving a per-module "zero tests is acceptable" opt-in (#7457) by @Copilot in [#9724](https://github.com/microsoft/testfx/pull/9724) ### Fixed diff --git a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs index 07b78c69eb..a7ba314c62 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs @@ -150,9 +150,13 @@ public int GetProcessExitCode() // tell an explicit-minimum violation apart from a plain "ran nothing" run (e.g. so a // `dotnet test --test-modules` orchestrator can distinguish a stricter local minimum from an // empty module). See issue #7457. - if (_commandLineOptions.TryGetOptionArgumentList(PlatformCommandLineProvider.MinimumExpectedTestsOptionKey, out string[]? argumentList)) + // A malformed value (e.g. present with no argument) is rejected earlier by option validation, but + // we still guard the parse defensively and fall back to the zero-tests verdict if it ever slips through. + if (_commandLineOptions.TryGetOptionArgumentList(PlatformCommandLineProvider.MinimumExpectedTestsOptionKey, out string[]? argumentList) + && argumentList is [string minimumExpectedTestsArgument] + && int.TryParse(minimumExpectedTestsArgument, out int minimumExpectedTests)) { - exitCode = exitCode == ExitCode.Success && _totalRanTests < int.Parse(argumentList[0], CultureInfo.InvariantCulture) ? ExitCode.MinimumExpectedTestsPolicyViolation : exitCode; + exitCode = exitCode == ExitCode.Success && _totalRanTests < minimumExpectedTests ? ExitCode.MinimumExpectedTestsPolicyViolation : exitCode; } else { From f5c907295ab42b4faf4d355732de3f31f80925ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 8 Jul 2026 17:39:31 +0200 Subject: [PATCH 4/4] Revert '--minimum-expected-tests 0' support (#7457) Reverts the #9724 change that allowed the literal value '--minimum-expected-tests 0'. Keeping '0' invalid restores an unambiguous meaning for GetMinimumExpectedTests() == 0 ('option not set'), which avoids the terminal-reporter verdict divergence tracked in #9744: with '--min 0' the exit code was 0 (success) while the terminal still rendered a failed 'Zero tests ran' verdict, because the shared verdict helpers could not distinguish 'unset' from 'explicit 0' without a cross-repo change to the vendored TerminalTestReporterOptions. Issue #7457 item #2 ('--min 0 == --ignore-exit-code 8') remains served by the existing '--ignore-exit-code 8'. The load-bearing behavior for the 'dotnet test --test-modules' orchestrator -- an explicit '--minimum-expected-tests N' governs the zero-tests verdict (exit code 9, not 8) -- is unaffected and stays. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/Changelog-Platform.md | 1 - .../PlatformCommandLineProvider.cs | 2 +- .../Resources/PlatformResources.resx | 2 +- .../Resources/xlf/PlatformResources.cs.xlf | 4 ++-- .../Resources/xlf/PlatformResources.de.xlf | 4 ++-- .../Resources/xlf/PlatformResources.es.xlf | 4 ++-- .../Resources/xlf/PlatformResources.fr.xlf | 4 ++-- .../Resources/xlf/PlatformResources.it.xlf | 4 ++-- .../Resources/xlf/PlatformResources.ja.xlf | 4 ++-- .../Resources/xlf/PlatformResources.ko.xlf | 4 ++-- .../Resources/xlf/PlatformResources.pl.xlf | 4 ++-- .../Resources/xlf/PlatformResources.pt-BR.xlf | 4 ++-- .../Resources/xlf/PlatformResources.ru.xlf | 4 ++-- .../Resources/xlf/PlatformResources.tr.xlf | 4 ++-- .../xlf/PlatformResources.zh-Hans.xlf | 4 ++-- .../xlf/PlatformResources.zh-Hant.xlf | 4 ++-- .../ExecutionTests.cs | 14 +------------ .../PlatformCommandLineProviderTests.cs | 20 ++----------------- .../Services/TestApplicationResultTests.cs | 17 ---------------- 19 files changed, 31 insertions(+), 77 deletions(-) diff --git a/docs/Changelog-Platform.md b/docs/Changelog-Platform.md index ad7637332f..67f7770869 100644 --- a/docs/Changelog-Platform.md +++ b/docs/Changelog-Platform.md @@ -49,7 +49,6 @@ See full log [of v4.2.3...v4.3.0](https://github.com/microsoft/testfx/compare/v4 * Add server-initiated session cancellation to the dotnet test IPC protocol by @Evangelink in [#9549](https://github.com/microsoft/testfx/pull/9549) * Emit `::warning` annotations for skipped tests in `Microsoft.Testing.Extensions.GitHubActionsReport` by @Evangelink in [#9641](https://github.com/microsoft/testfx/pull/9641) * Let an explicit `--minimum-expected-tests N` govern the zero-tests verdict, so a run of fewer than N tests reports the minimum-expected violation (exit code 9) instead of "zero tests ran" (exit code 8) even when no tests ran. This lets a `dotnet test --test-modules` orchestrator tell a stricter local-minimum violation apart from an empty module (#7457) by @Copilot in [#9709](https://github.com/microsoft/testfx/pull/9709) -* Allow `--minimum-expected-tests 0` so an explicit zero minimum accepts an empty run (same outcome as `--ignore-exit-code 8`), giving a per-module "zero tests is acceptable" opt-in (#7457) by @Copilot in [#9724](https://github.com/microsoft/testfx/pull/9724) ### Fixed diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs index 990c0aa05f..50879c750c 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs @@ -202,7 +202,7 @@ public static bool IsListTestsJsonOutput(ICommandLineOptions commandLineOptions) private static Task IsMinimumExpectedTestsOptionValidAsync(CommandLineOption option, string[] arguments) => option.Name == MinimumExpectedTestsOptionKey - && (arguments.Length != 1 || !int.TryParse(arguments[0], out int value) || value < 0) + && (arguments.Length != 1 || !int.TryParse(arguments[0], out int value) || value <= 0) ? ValidationResult.InvalidTask(PlatformResources.PlatformCommandLineMinimumExpectedTestsOptionSingleArgument) : ValidationResult.ValidTask; diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index 8b07861e82..eba7e4715e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -497,7 +497,7 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print {Locked="--list-tests"}{Locked="--minimum-expected-tests"} - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 25004bf8f1..a8f18b45e4 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -591,9 +591,9 @@ Volitelně přijímá hodnotu „text“ (výchozí výstup čitelný pro člov - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - --minimum-expected-tests očekává jednu kladnou nenulovou celočíselnou hodnotu + --minimum-expected-tests očekává jednu kladnou nenulovou celočíselnou hodnotu (např. --minimum-expected-tests 10). {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 0af729de6d..3cc0f98381 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -591,9 +591,9 @@ Akzeptiert optional „text“ (die standardmäsige lesbare Ausgabe) oder „jso - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - "--minimum-expected-tests" erwartet einen einzelnen positiven ganzzahligen Wert ungleich Null + "--minimum-expected-tests" erwartet einen einzelnen positiven ganzzahligen Wert ungleich Null (Beispiel: "--minimum-expected-tests 10") {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 4f3969a0e3..9029a4b074 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -591,9 +591,9 @@ Opcionalmente, acepta "text" (la salida legible por el usuario predeterminada) o - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' espera un único valor entero positivo distinto de cero + '--minimum-expected-tests' espera un único valor entero positivo distinto de cero (por ejemplo, '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index 82b28299df..c8b87178f9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -591,9 +591,9 @@ Accepte éventuellement « text » (sortie lisible par l’humain par défaut) - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - « --minimum-expected-tests » attend une seule valeur entière positive différente de zéro + « --minimum-expected-tests » attend une seule valeur entière positive différente de zéro (par exemple, « --minimum-expected-tests 10 ») {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index 6a31ac096b..0fc26c2e8e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -591,9 +591,9 @@ Facoltativamente accetta ''text'' (output leggibile predefinito) o ''json'' per - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' prevede un singolo valore intero positivo diverso da zero + '--minimum-expected-tests' prevede un singolo valore intero positivo diverso da zero (ad esempio '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 096084bbc2..7b4ecde384 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -592,9 +592,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' には、0 以外の正の整数値が 1 つ必要です + '--minimum-expected-tests' には、0 以外の正の整数値が 1 つ必要です (例: '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 119ea840c9..b701d8459d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests'에는 0이 아닌 단일 양의 정수 값이 필요합니다. + '--minimum-expected-tests'에는 0이 아닌 단일 양의 정수 값이 필요합니다. (예: '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 55e73c3590..46ba603b81 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -591,9 +591,9 @@ Opcjonalnie akceptuje „text” (domyślne dane wyjściowe czytelne dla człowi - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - Opcja „--minimum-expected-tests” oczekuje pojedynczej niezerowej dodatniej liczby całkowitej + Opcja „--minimum-expected-tests” oczekuje pojedynczej niezerowej dodatniej liczby całkowitej (np. „--minimum-expected-tests 10”) {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index 71a17b8bcb..af0ad62dbd 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -591,9 +591,9 @@ Opcionalmente, aceita 'text' (a saída legível por humanos padrão) ou 'json' p - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' espera um único valor inteiro positivo diferente de zero + '--minimum-expected-tests' espera um único valor inteiro positivo diferente de zero (por exemplo, '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index fdb677cb8f..a424a69ea7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - "--minimum-expected-tests" ожидает единственное ненулевое положительное целое значение + "--minimum-expected-tests" ожидает единственное ненулевое положительное целое значение (например, "--minimum-expected-tests 10") {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index c9bd493775..3e1d58a17b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests', sıfır olmayan tek bir pozitif tamsayı değeri bekler + '--minimum-expected-tests', sıfır olmayan tek bir pozitif tamsayı değeri bekler (ör. '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 8d8390deb5..85a8ec4d5f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - "--minimum-expected-tests" 应有单个非零正整数值 + "--minimum-expected-tests" 应有单个非零正整数值 (例如 "--minimum-expected-tests 10") {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 57fb2d842e..0aea3dfde1 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -591,9 +591,9 @@ Optionally accepts 'text' (the default human-readable output) or 'json' to print - '--minimum-expected-tests' expects a single non-negative integer value + '--minimum-expected-tests' expects a single non-zero positive integer value (e.g. '--minimum-expected-tests 10') - '--minimum-expected-tests' 需要單一非零的正整數值 + '--minimum-expected-tests' 需要單一非零的正整數值 (例如 '--minimum-expected-tests 10') {Locked="--minimum-expected-tests"}{Locked="--minimum-expected-tests 10"} diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs index 3da5a4506b..fe14840d44 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs @@ -169,19 +169,7 @@ public async Task Exec_WhenMinimumExpectedTestsIsNegative_ResultIsNotOk(string t TestHostResult testHostResult = await testHost.ExecuteAsync("--minimum-expected-tests=-1", cancellationToken: TestContext.CancellationToken); testHostResult.AssertExitCodeIs(ExitCode.InvalidCommandLine); - testHostResult.AssertOutputContains("Option '--minimum-expected-tests' has invalid arguments: '--minimum-expected-tests' expects a single non-negative integer value"); - } - - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - [TestMethod] - public async Task Exec_WhenMinimumExpectedTestsIsZeroAndNoTestsRun_ResultIsOk(string tfm) - { - var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); - // The uid filter matches no test, so zero tests run. An explicit '--minimum-expected-tests 0' - // accepts that empty run and supersedes the "zero tests ran" (exit code 8) verdict. See issue #7457. - TestHostResult testHostResult = await testHost.ExecuteAsync("--filter-uid 2 --minimum-expected-tests 0", cancellationToken: TestContext.CancellationToken); - - testHostResult.AssertExitCodeIs(ExitCode.Success); + testHostResult.AssertOutputContains("Option '--minimum-expected-tests' has invalid arguments: '--minimum-expected-tests' expects a single non-zero positive integer value"); } [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs index 74313e812c..f2395774e9 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs @@ -215,12 +215,9 @@ public async Task IsInvalid_When_Both_FilterUid_And_TreenodeFilter_Provided() } [TestMethod] + [DataRow("0")] [DataRow("-1")] - [DataRow("-5")] - [DataRow("abc")] - [DataRow("")] - [DataRow("1.5")] - public async Task IsInvalid_When_MinimumExpectedTests_Is_Negative_Or_Not_An_Integer(string minimumExpectedTests) + public async Task IsInvalid_When_MinimumExpectedTests_Is_Not_Positive(string minimumExpectedTests) { var provider = new PlatformCommandLineProvider(); CommandLineOption option = provider.GetCommandLineOptions().First(x => x.Name == PlatformCommandLineProvider.MinimumExpectedTestsOptionKey); @@ -230,19 +227,6 @@ public async Task IsInvalid_When_MinimumExpectedTests_Is_Negative_Or_Not_An_Inte Assert.AreEqual(PlatformResources.PlatformCommandLineMinimumExpectedTestsOptionSingleArgument, validateOptionsResult.ErrorMessage); } - [TestMethod] - [DataRow("0")] - [DataRow("1")] - [DataRow("10")] - public async Task IsValid_When_MinimumExpectedTests_Is_NonNegative_Integer(string minimumExpectedTests) - { - var provider = new PlatformCommandLineProvider(); - CommandLineOption option = provider.GetCommandLineOptions().First(x => x.Name == PlatformCommandLineProvider.MinimumExpectedTestsOptionKey); - - ValidationResult validateOptionsResult = await provider.ValidateOptionArgumentsAsync(option, [minimumExpectedTests]).ConfigureAwait(false); - Assert.IsTrue(validateOptionsResult.IsValid); - } - [TestMethod] public async Task IsValid_When_DiscoverTests_HasNoArgument() { diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs index 877c05a783..4c3637f073 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs @@ -212,23 +212,6 @@ TestApplicationResult testApplicationResult Assert.AreEqual((int)ExitCode.MinimumExpectedTestsPolicyViolation, testApplicationResult.GetProcessExitCode()); } - [TestMethod] - public void GetProcessExitCodeAsync_If_MinimumExpectedTests_Zero_And_No_Tests_Ran_Returns_Success() - { - // An explicit `--minimum-expected-tests 0` accepts an empty run, superseding the ZeroTests (8) - // verdict. This is how a `dotnet test --test-modules` orchestrator flows "zero is acceptable for - // this module" down to each module. See issue #7457. - TestApplicationResult testApplicationResult - = new( - new Mock().Object, - new CommandLineOption(PlatformCommandLineProvider.MinimumExpectedTestsOptionKey, ["0"]), - new Mock().Object, - new Mock().Object, - null); - - Assert.AreEqual((int)ExitCode.Success, testApplicationResult.GetProcessExitCode()); - } - [TestMethod] public void GetProcessExitCodeAsync_If_MinimumExpectedTests_Set_And_No_Tests_Ran_Returns_MinimumExpectedTestsPolicyViolation() {