diff --git a/src/Platform/Microsoft.Testing.Platform.Internal.DotnetTest/Microsoft.Testing.Platform.Internal.DotnetTest.csproj b/src/Platform/Microsoft.Testing.Platform.Internal.DotnetTest/Microsoft.Testing.Platform.Internal.DotnetTest.csproj index 047cc06b06..bbfc1f3147 100644 --- a/src/Platform/Microsoft.Testing.Platform.Internal.DotnetTest/Microsoft.Testing.Platform.Internal.DotnetTest.csproj +++ b/src/Platform/Microsoft.Testing.Platform.Internal.DotnetTest/Microsoft.Testing.Platform.Internal.DotnetTest.csproj @@ -84,12 +84,22 @@ This is an INTERNAL, source-only package: it shares - as compiled source - the p BuildAction="Compile" PackagePath="contentFiles/cs/any/TerminalReporter/%(Filename)%(Extension)" /> + + + .props). It wires the terminal reporter's localized resources - shipped by this package under build/TerminalReporter/ - into the consumer's own compilation: - * The resx is added as a strongly-typed (Generator="MSBuild:Compile" plus the - StronglyTyped* metadata) so the consumer's build generates the `TerminalResources` accessor and embeds - the strings into the consumer assembly. This does not depend on Arcade's GenerateSource pipeline. - * StronglyTypedNamespace/StronglyTypedClassName pin the generated accessor to - Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalResources - the type the shared reporter source - expects - regardless of the consumer's RootNamespace, and ManifestResourceName keeps the embedded - manifest name in sync so the runtime ResourceManager lookup resolves the same resource set. - * The sibling xlf/ folder lets XliffTasks emit satellite assemblies for each language. This requires the - consumer to have XliffTasks; dotnet/sdk (the intended consumer) has it via Arcade. + * The resx is added as an using the Arcade/XliffTasks convention + (dotnet/sdk, the intended consumer, provides both): the consumer's build generates the `TerminalResources` + strongly-typed accessor (embedding the strings into the consumer assembly, with the accessor's + ResourceManager bound to the consumer assembly) AND lets XliffTasks emit per-language satellites from the + sibling xlf/ folder. We intentionally do NOT use the manual Generator="MSBuild:Compile" + StronglyTyped* + metadata here: that path collides with XliffTasks (the per-culture resx XliffTasks generates inherit the + StronglyTyped metadata, so GenerateResource sees multiple sources for one strongly-typed class -> MSB3573). + * Namespace pins the generated accessor to Microsoft.Testing.Platform.OutputDevice.Terminal (the namespace the + shared reporter source expects) regardless of the consumer's RootNamespace; the class name defaults to the + resx file name (TerminalResources). ManifestResourceName pins the embedded resource name to + Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalResources so the generated accessor's ResourceManager + resolves it. We deliberately do NOT set Link: the resx lives outside the consumer's project cone (it ships in + this package), and a Link would feed into the derived manifest resource name / accessor binding, which is + exactly what TerminalReporterContract.props avoids for the same reason. --> + GenerateSource="true" + Namespace="Microsoft.Testing.Platform.OutputDevice.Terminal" + ManifestResourceName="Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalResources" /> diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs index 8002d4296e..72938eee78 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs @@ -28,7 +28,7 @@ internal static FlatException[] Flatten(string? errorMessage, Exception? excepti IEnumerable aggregateExceptions = exception switch { AggregateException aggregate => aggregate.Flatten().InnerExceptions, - _ => [exception?.InnerException], + _ => new Exception?[] { exception?.InnerException }, }; foreach (Exception? aggregate in aggregateExceptions) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalResources.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalResources.cs index 6fc23a4e7a..5fdd938848 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalResources.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalResources.cs @@ -41,8 +41,18 @@ internal static partial class TerminalResources internal static string @ConsoleIsAlreadyInBatchingMode => GetResourceString("ConsoleIsAlreadyInBatchingMode"); + internal static string @DiscoveredTestsInAssembly => GetResourceString("DiscoveredTestsInAssembly"); + + internal static string @DiscoveredTestsSummary => GetResourceString("DiscoveredTestsSummary"); + + internal static string @DiscoveredTestsSummarySingular => GetResourceString("DiscoveredTestsSummarySingular"); + + internal static string @DiscoveringTestsFrom => GetResourceString("DiscoveringTestsFrom"); + internal static string @DurationLowercase => GetResourceString("DurationLowercase"); + internal static string @Error => GetResourceString("Error"); + internal static string @ExitCode => GetResourceString("ExitCode"); internal static string @Expected => GetResourceString("Expected"); @@ -69,6 +79,10 @@ internal static partial class TerminalResources internal static string @PressCtrlCAgainToForceExit => GetResourceString("PressCtrlCAgainToForceExit"); + internal static string @Retried => GetResourceString("Retried"); + + internal static string @RunningTestsFrom => GetResourceString("RunningTestsFrom"); + internal static string @SkippedLowercase => GetResourceString("SkippedLowercase"); internal static string @StackFrameAt => GetResourceString("StackFrameAt"); @@ -119,6 +133,8 @@ internal static partial class TerminalResources internal static string @TotalLowercase => GetResourceString("TotalLowercase"); + internal static string @Try => GetResourceString("Try"); + internal static string @ZeroTestsRan => GetResourceString("ZeroTestsRan"); #endif diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalResources.resx b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalResources.resx index e2d470c93a..1f05ef9786 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalResources.resx @@ -290,4 +290,36 @@ Valid values are 'All', 'Failed', 'None'. Default is 'All' (or 'Failed' when an failed with {0} error(s) {0} is the number of errors in an assembly summary line + + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + + + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + + + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + + + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + + + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Handshake.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Handshake.cs index 3ade68c58e..af07e4b686 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Handshake.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Handshake.cs @@ -31,6 +31,20 @@ public bool HasHandshakeFailure } } + /// + /// Gets the number of assemblies that failed to handshake. Counted toward the run summary's "error" line. + /// + private int HandshakeFailureCount + { + get + { + lock (_handshakeFailuresLock) + { + return _handshakeFailures.Count; + } + } + } + /// /// Report that an assembly failed to produce a usable handshake. This is an orchestrator-only path (the /// in-process host always handshakes); it records the failure so flips and diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Lifecycle.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Lifecycle.cs index 71df06f231..dea0312569 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Lifecycle.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Lifecycle.cs @@ -9,11 +9,13 @@ namespace Microsoft.Testing.Platform.OutputDevice.Terminal; internal sealed partial class TerminalTestReporter { private bool _isHelp; + private bool _isRetry; public void TestExecutionStarted(DateTimeOffset testStartTime, int workerCount, bool isDiscovery, bool isHelp, bool isRetry) { _isDiscovery = isDiscovery; _isHelp = isHelp; + _isRetry = isRetry; _testExecutionStartTime = testStartTime; _terminalWithProgress.StartShowingProgress(workerCount); } @@ -24,6 +26,33 @@ public void AssemblyRunStarted(string assembly, string? targetFramework, string? // in-process host starts a single assembly with a single fixed instance id (one attempt). TestProgressState assemblyRun = GetOrAddAssemblyRun(assembly, targetFramework, architecture, executionId); assemblyRun.NotifyHandshake(instanceId); + + // Defensive: even if the orchestrator did not flag the run as a retry up front (e.g. the retry parameter + // could not be parsed), a second handshake for the same assembly means a retry is happening. Flip _isRetry + // so the per-test "(try N)" annotation and the summary's "(+N retried)" suffix are shown. The in-process + // host only ever handshakes once (TryCount stays 1), so this never trips for it. + _isRetry |= assemblyRun.TryCount > 1; + + // Orchestrator-only: print the per-assembly "Running tests from " banner (or "Discovering tests + // from" in discovery mode), prefixed with "(try N)" on a retry. Gated on ShowAssembly + ShowAssemblyStartAndComplete, + // which the in-process host leaves off, so its output is unchanged. + if (_options.ShowAssembly && _options.ShowAssemblyStartAndComplete) + { + _terminalWithProgress.WriteToTerminal(terminal => + { + if (_isRetry) + { + terminal.SetColor(TerminalColor.DarkGray); + terminal.Append($"({string.Format(CultureInfo.CurrentCulture, TerminalResources.Try, assemblyRun.TryCount)}) "); + terminal.ResetColor(); + } + + terminal.Append(_isDiscovery ? TerminalResources.DiscoveringTestsFrom : TerminalResources.RunningTestsFrom); + terminal.Append(' '); + AppendAssemblyLinkTargetFrameworkAndArchitecture(terminal, assembly, targetFramework, architecture); + terminal.AppendLine(); + }); + } } private TestProgressState GetOrAddAssemblyRun(string assembly, string? targetFramework, string? architecture, string executionId) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Messaging.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Messaging.cs index 64461e536f..5807f3f16c 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Messaging.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Messaging.cs @@ -43,6 +43,21 @@ private void WriteMessage(string text, TerminalColor? color = null, int? padding } }); + /// + /// Orchestrator overload (dotnet test): carries the assembly/target-framework/architecture and per-attempt + /// instance id known to the multi-process orchestrator. The shared in-progress tracking is keyed by execution id, + /// so those extra arguments are accepted for signature parity and the overload delegates to the core method. + /// + public void TestInProgress( + string assembly, + string? targetFramework, + string? architecture, + string executionId, + string instanceId, + string testNodeUid, + string displayName) + => TestInProgress(executionId, testNodeUid, displayName); + public void TestInProgress( string executionId, string testNodeUid, diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Summary.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Summary.cs index 061f4201c4..474fddf337 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Summary.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.Summary.cs @@ -56,12 +56,17 @@ private void AppendTestRunSummary(ITerminal terminal) // Two sibling sites mirror this decision and must stay in lockstep: // - TestApplicationResult.ConsumeAsync (excludes skipped from `_totalRanTests` -> exit code 8) // - Microsoft.Testing.Platform.MSBuild InvokeTestingPlatformTask (run-summary verdict) - bool runFailed = TestRunSummaryHelper.IsRunFailed(totalTests, totalFailedTests, totalSkippedTests, WasCancelled, _options.MinimumExpectedTests) || HasHandshakeFailure; + // Orchestrator-only: an assembly whose process ended unsuccessfully (crash / non-zero exit) with no failed + // tests is still a run failure. Gated on ShowAssembly (the orchestrator marker): the in-process host leaves + // ShowAssembly off and never sets Success, so this stays false and its verdict/color are unchanged. + bool hasFailedAssemblies = _options.ShowAssembly && assemblies.Any(static a => !a.Success); + + bool runFailed = TestRunSummaryHelper.IsRunFailed(totalTests, totalFailedTests, totalSkippedTests, WasCancelled, _options.MinimumExpectedTests) || HasHandshakeFailure || hasFailedAssemblies; terminal.SetColor(runFailed ? TerminalColor.DarkRed : TerminalColor.DarkGreen); terminal.Append(TerminalResources.TestRunSummary); terminal.Append(' '); - terminal.Append(TestRunSummaryHelper.GetVerdictText(totalTests, totalFailedTests, totalSkippedTests, WasCancelled, _options.MinimumExpectedTests)); + terminal.Append(TestRunSummaryHelper.GetVerdictText(totalTests, totalFailedTests, totalSkippedTests, WasCancelled, _options.MinimumExpectedTests, HasHandshakeFailure, hasFailedAssemblies)); // For a single assembly (the in-process host) the verdict is followed by the assembly link, exactly as // before. For multiple assemblies (the dotnet test orchestrator) the per-assembly identity is rendered in @@ -94,20 +99,47 @@ private void AppendTestRunSummary(ITerminal terminal) int failed = totalFailedTests; int passed = totalPassedTests; int skipped = totalSkippedTests; + int retried = assemblies.Sum(static a => a.RetriedFailedTests); + + // Orchestrator-only: count assemblies that ended unsuccessfully without a failed test (crash / non-zero exit) + // plus handshake failures. These are surfaced as an "error: N" line so they aren't hidden behind a zero + // failed-test count. In-process leaves ShowAssembly off and never has handshake failures, so error is 0. + int error = (_options.ShowAssembly ? assemblies.Count(static a => !a.Success && a.FailedTests == 0) : 0) + HandshakeFailureCount; TimeSpan runDuration = _testExecutionStartTime != null && _testExecutionEndTime != null ? (_testExecutionEndTime - _testExecutionStartTime).Value : TimeSpan.Zero; bool colorizeFailed = failed > 0; bool colorizePassed = passed > 0 && failed == 0; bool colorizeSkipped = skipped > 0 && skipped == total && failed == 0; + string errorText = $"{SingleIndentation}{TerminalResources.Error}: {error}"; string totalText = $"{SingleIndentation}{TerminalResources.TotalLowercase}: {total}"; string failedText = $"{SingleIndentation}{TerminalResources.FailedLowercase}: {failed}"; string passedText = $"{SingleIndentation}{TerminalResources.SucceededLowercase}: {passed}"; string skippedText = $"{SingleIndentation}{TerminalResources.SkippedLowercase}: {skipped}"; string durationText = $"{SingleIndentation}{TerminalResources.DurationLowercase}: "; + if (error > 0) + { + terminal.SetColor(TerminalColor.DarkRed); + terminal.AppendLine(errorText); + terminal.ResetColor(); + terminal.AppendLine(); + } + terminal.ResetColor(); - terminal.AppendLine(totalText); + terminal.Append(totalText); + + // Orchestrator-only: when failed tests were retried, append "(+N retried)" after the total so the headline + // count (which reflects the final attempt) is reconciled with the extra retried executions. retried is 0 for + // the in-process host, so the total line stays byte-identical there. + if (retried > 0) + { + terminal.SetColor(TerminalColor.DarkGray); + terminal.Append($" (+{retried} {TerminalResources.Retried})"); + terminal.ResetColor(); + } + + terminal.AppendLine(); if (colorizeFailed) { terminal.SetColor(TerminalColor.DarkRed); @@ -153,6 +185,34 @@ private void AppendTestRunSummary(ITerminal terminal) AppendHandshakeFailureRecap(terminal); } + /// + /// Orchestrator overload (dotnet test): the multi-process orchestrator also knows each discovered test's + /// uid, file path and line number. The shared discovery summary currently lists display names only, so those are + /// accepted for signature parity. When is missing the is used + /// as the listed name; when neither is available the test is still counted (so the discovery total stays correct) + /// but no blank entry is added to the summary. + /// + internal void TestDiscovered(string executionId, string? displayName, string? uid, string? filePath, int? lineNumber) + { + // Prefer the display name, fall back to the uid so the discovered test is still listed by something. + string? name = displayName ?? uid; + if (name is not null) + { + TestDiscovered(executionId, name); + return; + } + + // No name available at all: still increment the discovered count so the discovery summary total stays + // correct (in discovery mode TotalTests is computed from DiscoveredTests), but avoid adding a blank entry. + if (!_assemblies.TryGetValue(executionId, out TestProgressState? asm)) + { + throw ApplicationStateGuard.Unreachable(); + } + + asm.DiscoveredTests++; + _terminalWithProgress.UpdateWorker(asm.SlotIndex); + } + internal void TestDiscovered(string executionId, string displayName) { if (!_assemblies.TryGetValue(executionId, out TestProgressState? asm)) @@ -177,6 +237,42 @@ public void AppendTestDiscoverySummary(ITerminal terminal) int totalTests = assemblies.Sum(static a => a.TotalTests); bool runFailed = WasCancelled || totalTests < 1; + if (_options.ShowAssembly) + { + // Orchestrator (dotnet test): a per-assembly "Discovered N tests in assembly - " header followed by + // the discovered test names, then a run-level total ("Discovered N tests." / "... in N assemblies."). + foreach (TestProgressState assembly in assemblies) + { + terminal.Append(string.Format(CultureInfo.CurrentCulture, TerminalResources.DiscoveredTestsInAssembly, assembly.DiscoveredTestDisplayNames.Count)); + terminal.Append(" - "); + AppendAssemblyLinkTargetFrameworkAndArchitecture(terminal, assembly); + terminal.AppendLine(); + foreach (string displayName in assembly.DiscoveredTestDisplayNames) + { + terminal.Append(SingleIndentation); + terminal.AppendLine(displayName); + } + + terminal.AppendLine(); + } + + terminal.SetColor(runFailed ? TerminalColor.DarkRed : TerminalColor.DarkGreen); + terminal.AppendLine(assemblies.Count <= 1 + ? string.Format(CultureInfo.CurrentCulture, TerminalResources.DiscoveredTestsSummarySingular, totalTests) + : string.Format(CultureInfo.CurrentCulture, TerminalResources.DiscoveredTestsSummary, totalTests, assemblies.Count)); + terminal.ResetColor(); + terminal.AppendLine(); + + if (WasCancelled) + { + terminal.Append(TerminalResources.Aborted); + terminal.AppendLine(); + } + + return; + } + + // In-process host: the single "Test discovery summary: found N test(s)" format (unchanged shipping output). foreach (TestProgressState assembly in assemblies) { foreach (string displayName in assembly.DiscoveredTestDisplayNames) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.TestCompletion.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.TestCompletion.cs index 54bc468198..7824a5b256 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.TestCompletion.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.TestCompletion.cs @@ -121,8 +121,12 @@ private void TestCompleted( _terminalWithProgress.NotifyTestCompleted(); if (outcome != TestOutcome.Passed || GetShowPassedTests()) { + // Capture the attempt number (1-based) at completion time so the per-test "(try N)" annotation reflects + // the retry attempt this result belongs to. + int attempt = asm.TryCount; _terminalWithProgress.WriteToTerminal(terminal => RenderTestCompleted( terminal, + attempt, displayName, outcome, duration, @@ -143,6 +147,7 @@ private bool GetShowPassedTests() private void RenderTestCompleted( ITerminal terminal, + int attempt, string displayName, TestOutcome outcome, TimeSpan? duration, @@ -176,6 +181,16 @@ private void RenderTestCompleted( terminal.SetColor(color); terminal.Append(outcomeText); + + // Orchestrator-only: annotate which retry attempt this result belongs to (e.g. "failed (try 2)") so retried + // results are not mistaken for duplicates. _isRetry is only ever set for the dotnet test orchestrator; the + // in-process host leaves it false, so its per-test lines are unchanged. + if (_isRetry) + { + terminal.SetColor(TerminalColor.DarkGray); + terminal.Append($" ({string.Format(CultureInfo.CurrentCulture, TerminalResources.Try, attempt)})"); + } + terminal.ResetColor(); terminal.Append(' '); terminal.Append(MakeControlCharactersVisible(displayName, true)); diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.cs.xlf index 488c748906..fc6974560c 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.cs.xlf @@ -27,11 +27,36 @@ Konzole je již v režimu dávkování. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration doba trvání + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Dalším stisknutím kombinace kláves Ctrl+C vynutíte ukončení. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped vynecháno @@ -245,6 +280,11 @@ Platné hodnoty jsou All, Failed, None. Výchozí hodnota je All (nebo Failed, k Souhrn testovacího běhu: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran Spustila se nula testů diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.de.xlf index f6af1b03f8..f4b51894c5 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.de.xlf @@ -27,11 +27,36 @@ Die Konsole befindet sich bereits im Batchmodus. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration Dauer + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Drücken Sie erneut Ctrl+C, um das Beenden zu erzwingen. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped übersprungen @@ -245,6 +280,11 @@ Gültige Werte sind „All“, „Failed“ und „None“. Der Standardwert ist Testlaufzusammenfassung: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran Es wurden keine Tests ausgeführt. diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.es.xlf index 42d2f65462..8fe5a2b1f4 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.es.xlf @@ -27,11 +27,36 @@ La consola ya está en modo de procesamiento por lotes. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration duración + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Presione Ctrl+C de nuevo para forzar la salida. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped omitido @@ -245,6 +280,11 @@ Los valores válidos son "All", "Failed", "None". El valor predeterminado es "Al Resumen de la serie de pruebas: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran No se ejecutaron pruebas diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.fr.xlf index 75fa3148d2..cf86565c77 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.fr.xlf @@ -27,11 +27,36 @@ La console est déjà en mode de traitement par lot. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration durée + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Appuyez de nouveau sur Ctrl+C pour forcer la fermeture. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped ignoré @@ -245,6 +280,11 @@ Les valeurs valides sont « All », « Failed » et « None ». La valeur Résumé de série de tests : + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran Zéro tests exécutés diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.it.xlf index 42ce264d49..60a0383ab7 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.it.xlf @@ -27,11 +27,36 @@ La console è già in modalità batch. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration durata + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Premere di nuovo Ctrl+C per forzare l'uscita. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped ignorato @@ -245,6 +280,11 @@ I valori validi sono 'All', 'Failed', 'None'. L'impostazione predefinita è 'All Riepilogo esecuzione test: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran Nessun test eseguito diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ja.xlf index 76e47c0870..2a82a0ccfc 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ja.xlf @@ -27,11 +27,36 @@ コンソールは既にバッチ 処理モードです。 Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration 期間 + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ 強制終了するには、Ctrl+C キーをもう一度押してください。 {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped スキップされました @@ -245,6 +280,11 @@ Valid values are 'All', 'Failed', 'None'. Default is 'All' (or 'Failed' when an テストの実行の概要: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran 0 件のテストが実行されました diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ko.xlf index 857ec0b946..aa01a7c582 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ko.xlf @@ -27,11 +27,36 @@ 콘솔이 이미 일괄 처리 모드에 있습니다. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration 기간 + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ 강제 종료하려면 Ctrl+C를 한 번 더 누르세요. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped 건너뜀 @@ -245,6 +280,11 @@ Valid values are 'All', 'Failed', 'None'. Default is 'All' (or 'Failed' when an 테스트 실행 요약: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran 테스트가 0개 실행됨 diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.pl.xlf index a74e6605ed..4278e72944 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.pl.xlf @@ -27,11 +27,36 @@ Konsola jest już w trybie dzielenia na partie. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration czas trwania + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Naciśnij ponownie klawisze Ctrl+C, aby wymusić wyjście. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped pominięte @@ -245,6 +280,11 @@ Prawidłowe wartości to „All”, „Failed”, „None”. Wartość domyśln Podsumowanie przebiegu testu: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran Uruchomiono zero testów diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.pt-BR.xlf index 8faa2210f5..4ae1c42697 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.pt-BR.xlf @@ -27,11 +27,36 @@ O console já está no modo de lote. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration duração + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Pressione Ctrl+C de novo para forçar a saída. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped ignorado @@ -245,6 +280,11 @@ Os valores válidos são 'All', 'Failed', 'None'. O padrão é 'All' (ou 'Failed Resumo da execução de teste: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran Zero testes executados diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ru.xlf index ef0b14ba0a..9c0353b141 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.ru.xlf @@ -27,11 +27,36 @@ Консоль уже находится в пакетном режиме. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration длительность + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Нажмите Ctrl+C еще раз, чтобы выполнить принудительный выход. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped пропущено @@ -245,6 +280,11 @@ Valid values are 'All', 'Failed', 'None'. Default is 'All' (or 'Failed' when an Сводка тестового запуска: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran Запущено ноль тестов diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.tr.xlf index ea8639093b..3b10a171a4 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.tr.xlf @@ -27,11 +27,36 @@ Konsol zaten işlem grubu oluşturma modunda bulunuyor. Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration süre + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ Çıkmayı zorlamak için Ctrl+C tuşlarına yeniden basın. {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped atlandı @@ -245,6 +280,11 @@ Geçerli değerler: 'All', 'Failed', 'None'. Varsayılan değer 'All' (veya bir Test çalıştırması özeti: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran Sıfır test çalıştırıldı diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.zh-Hans.xlf index e21ef7a75a..dab322b442 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.zh-Hans.xlf @@ -27,11 +27,36 @@ 控制台已处于批处理模式。 Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration 持续时间 + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ 再次按 Ctrl+C 强制退出。 {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped 已跳过 @@ -245,6 +280,11 @@ Valid values are 'All', 'Failed', 'None'. Default is 'All' (or 'Failed' when an 测试运行摘要: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran 运行了零个测试 diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.zh-Hant.xlf index 2b77bab0f5..99ea762772 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/xlf/TerminalResources.zh-Hant.xlf @@ -27,11 +27,36 @@ 主控台已處於批次處理模式。 Exception that is thrown when console is already collecting input into a batch (into a string builder), and code asks to enable batching mode again. + + Discovered {0} tests in assembly + Discovered {0} tests in assembly + Per-assembly discovery header printed by the dotnet test orchestrator; followed by the assembly path/target framework/architecture. {0} is the discovered test count. + + + Discovered {0} tests in {1} assemblies. + Discovered {0} tests in {1} assemblies. + dotnet test orchestrator discovery total across multiple assemblies. {0} is the discovered test count, {1} the assembly count. + + + Discovered {0} tests. + Discovered {0} tests. + dotnet test orchestrator discovery total for a single assembly. {0} is the discovered test count. + + + Discovering tests from + Discovering tests from + Per-assembly banner printed by the dotnet test orchestrator before discovering tests in an assembly; followed by the assembly path/target framework/architecture. + duration 持續時間 + + error + error + Label for the count of assemblies that failed without producing a failed test (crash / non-zero exit / handshake failure) in the run summary, e.g. 'error: 1'. + Exit code Exit code @@ -107,6 +132,16 @@ 再次按 Ctrl+C 以強制離開。 {Locked="Ctrl+C"} + + retried + retried + Suffix appended to the total test count in the run summary to indicate how many failed tests were retried, e.g. 'total: 5 (+2 retried)'. + + + Running tests from + Running tests from + Per-assembly banner printed by the dotnet test orchestrator before running an assembly; followed by the assembly path/target framework/architecture. + skipped 已跳過 @@ -245,6 +280,11 @@ Valid values are 'All', 'Failed', 'None'. Default is 'All' (or 'Failed' when an 測試回合摘要: + + try {0} + try {0} + number or tries of the current test assembly when test assembly is being retried. {0} is number that starts at 1 + Zero tests ran 已執行零項測試 diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TestRunSummaryHelper.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TestRunSummaryHelper.cs index 0b6a29c1ec..797d4213a1 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TestRunSummaryHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TestRunSummaryHelper.cs @@ -27,13 +27,27 @@ internal static bool IsRunFailed(int totalTests, int failedTests, int skippedTes /// /// Computes the verdict string for the test run. /// - internal static string GetVerdictText(int totalTests, int failedTests, int skippedTests, bool wasCancelled, int minimumExpectedTests) + /// + /// The two orchestrator-only flags surface non-test failures that must not be masked by the test-count wording: + /// + /// : at least one assembly failed to hand-shake. This escalates to + /// "Failed!" ahead of the "Zero tests ran" branch (a handshake failure is not a benign empty run). + /// : at least one assembly process ended unsuccessfully (e.g. crashed + /// or returned a non-zero exit code) even though its tests passed. This escalates to "Failed!" but only AFTER the + /// "Zero tests ran" branch, so a project that legitimately contains zero tests (which exits non-zero by design) + /// is still reported as "Zero tests ran" rather than a failure. + /// + /// In-process callers never have either condition and pass , so their verdict is unchanged. + /// + internal static string GetVerdictText(int totalTests, int failedTests, int skippedTests, bool wasCancelled, int minimumExpectedTests, bool hasHandshakeFailures = false, bool hasFailedAssemblies = false) => true switch { _ when wasCancelled => TerminalResources.Aborted, _ when totalTests < minimumExpectedTests => string.Format(CultureInfo.CurrentCulture, TerminalResources.MinimumExpectedTestsPolicyViolation, totalTests, minimumExpectedTests), - _ when totalTests == 0 || totalTests == skippedTests => TerminalResources.ZeroTestsRan, _ when failedTests > 0 => $"{TerminalResources.Failed}!", + _ when hasHandshakeFailures => $"{TerminalResources.Failed}!", + _ when totalTests == 0 || totalTests == skippedTests => TerminalResources.ZeroTestsRan, + _ when hasFailedAssemblies => $"{TerminalResources.Failed}!", _ => $"{TerminalResources.Passed}!", }; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs index 07f2fc4ea8..47e2f4af70 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs @@ -1137,6 +1137,106 @@ public void TerminalTestReporter_WhenInDiscoveryMode_ShouldIncrementDiscoveredTe Assert.IsTrue(output.Contains('2') || output.Contains("TestMethod1"), "Output should contain information about discovered tests"); } + [TestMethod] + public void TerminalTestReporter_WhenOrchestratorDiscoveryDisplayNameIsNull_CountsTestAndFallsBackToUid() + { + // Arrange + string assembly = "test.dll"; + string targetFramework = "net8.0"; + string architecture = "x64"; + var stringBuilderConsole = new StringBuilderConsole(); + var terminalReporter = new TerminalTestReporter(stringBuilderConsole, static () => false, new TerminalTestReporterOptions + { + ShowPassedTests = () => false, + AnsiMode = AnsiMode.NoAnsi, + ShowProgress = () => false, + }); + + DateTimeOffset startTime = DateTimeOffset.MinValue; + DateTimeOffset endTime = DateTimeOffset.MaxValue; + + // Act + terminalReporter.TestExecutionStarted(startTime, 1, isDiscovery: true, isHelp: false, isRetry: false); + terminalReporter.AssemblyRunStarted(assembly, targetFramework, architecture, "0", "0"); + + // No display name and no uid: counted, but must not add a blank indented entry. + terminalReporter.TestDiscovered("0", displayName: null, uid: null, filePath: null, lineNumber: null); + // No display name but a uid: the uid is used as the listed name. + terminalReporter.TestDiscovered("0", displayName: null, uid: "uid-fallback", filePath: null, lineNumber: null); + // Normal display name. + terminalReporter.TestDiscovered("0", "TestMethod1", uid: "uid-1", filePath: null, lineNumber: null); + + // Assert - every discovered test is counted (even the unnamed one). TotalTests is computed from + // DiscoveredTests in discovery mode and is cleared by TestExecutionCompleted, so assert it before that. + Assert.AreEqual(3, terminalReporter.TotalTests); + + terminalReporter.AssemblyRunCompleted("0"); + terminalReporter.TestExecutionCompleted(endTime, exitCode: null); + + string[] outputLines = stringBuilderConsole.Output.Replace("\r\n", "\n").Replace('\r', '\n').Split('\n'); + + // Assert - no blank indented entry for the unnamed test, but the uid fallback and display name are listed. + Assert.DoesNotContain(TerminalTestReporter.SingleIndentation, outputLines); + Assert.Contains($"{TerminalTestReporter.SingleIndentation}uid-fallback", outputLines); + Assert.Contains($"{TerminalTestReporter.SingleIndentation}TestMethod1", outputLines); + } + + [TestMethod] + public void TerminalTestReporter_OrchestratorTestInProgress_TracksActiveTestLikeCoreOverload() + { + // The orchestrator (dotnet test) TestInProgress overload carries extra assembly/target-framework/architecture + // and per-attempt instance metadata for call-site parity, but must track the active test exactly like the core + // (executionId, uid, displayName) overload. Verify the orchestrator-driven test surfaces in the active-test + // progress frame: its display name only appears in the output if it was registered as a running test. + string targetFramework = "net8.0"; + string architecture = "x64"; + string assembly = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\work\assembly.dll" : "/mnt/work/assembly.dll"; + + var stringBuilderConsole = new StringBuilderConsole(); + var stopwatchFactory = new StopwatchFactory(); + var terminalReporter = new TerminalTestReporter(stringBuilderConsole, static () => false, new TerminalTestReporterOptions + { + ShowPassedTests = () => true, + AnsiMode = AnsiMode.ForceAnsi, + ShowActiveTests = true, + ShowProgress = () => true, + }) + { + CreateStopwatch = stopwatchFactory.CreateStopwatch, + }; + + var startHandle = new AutoResetEvent(initialState: false); + var stopHandle = new AutoResetEvent(initialState: false); + + // Disable the timer updates so the captured output is deterministic. + terminalReporter.OnProgressStartUpdate += (sender, args) => startHandle.WaitOne(); + terminalReporter.OnProgressStopUpdate += (sender, args) => stopHandle.Set(); + + DateTimeOffset startTime = DateTimeOffset.MinValue; + terminalReporter.TestExecutionStarted(startTime, 1, isDiscovery: false, isHelp: false, isRetry: false); + terminalReporter.AssemblyRunStarted(assembly, targetFramework, architecture, "0", "0"); + + // A core-overload active test we will complete to trigger a progress redraw. + terminalReporter.TestInProgress(executionId: "0", testNodeUid: "Trigger", displayName: "Trigger"); + stopwatchFactory.AddTime(TimeSpan.FromMilliseconds(1)); + + // The orchestrator overload (extra assembly/targetFramework/architecture/instanceId args). This test is never + // completed, so its name can only appear in the output via the active-test progress frame. + terminalReporter.TestInProgress(assembly, targetFramework, architecture, executionId: "0", instanceId: "0", testNodeUid: "OrchestratorActive1", displayName: "OrchestratorActive1"); + stopwatchFactory.AddTime(TimeSpan.FromSeconds(1)); + + // Completing the trigger test redraws the progress frame, which lists the still-active orchestrator test. + terminalReporter.TestCompleted("0", testNodeUid: "Trigger", "Trigger", TestOutcome.Passed, TimeSpan.FromSeconds(10), + informativeMessage: null, errorMessage: null, exception: null, expected: null, actual: null, standardOutput: null, errorOutput: null); + + string output = stringBuilderConsole.Output; + startHandle.Set(); + stopHandle.WaitOne(); + + // The orchestrator-driven test is registered as active and therefore rendered in the progress frame. + Assert.Contains("OrchestratorActive1", output); + } + [TestMethod] public void TerminalTestReporter_WhenMultipleAssemblies_AggregatesCountsAndOmitsAssemblyLinkOnVerdict() { @@ -1251,8 +1351,10 @@ public void AssemblyRunCompleted_WhenExecutionIdUnknown_SummaryReprintsRecapAndR Assert.Contains($"{TerminalResources.ExitCode}: 1", output); Assert.Contains("the err", output); - // No test ran, so the run verdict is the red "Zero tests ran" (runFailed also includes HasHandshakeFailure). - Assert.Contains(TerminalResources.ZeroTestsRan, output); + // The summary verdict escalates to "Failed!" rather than the benign "Zero tests ran": a handshake failure + // must not be masked as an empty run (dotnet/sdk#51608). The per-assembly immediate-failure context above + // still legitimately says "Zero tests ran" (the assembly really did register zero tests). + Assert.Contains($"{TerminalResources.TestRunSummary} {TerminalResources.Failed}!", output); // Per-run state is reset after completion so a subsequent session starts fresh. Assert.IsFalse(terminalReporter.HasHandshakeFailure); @@ -1461,11 +1563,101 @@ public void AssemblyRunCompleted_WhenTestsWereRetried_ShowsRetriedCount() Assert.Contains(ExpectedCounts(1, 0, 0, retried: 1), assemblyLine); } + // Companion to the test above driving the FULL lifecycle to validate the two retry-specific renderings the + // dotnet/sdk orchestrator acceptance test RunTestProjectWithWithRetryFeature_ShouldSucceed asserts: + // 1) each per-test result line is annotated with "(try N)" so retried attempts are distinguishable, and + // 2) the run summary's total line is suffixed with "(+N retried)". + // The in-process host never retries (isRetry stays false, TryCount stays 1), so neither rendering appears there. + [TestMethod] + public void TestExecutionCompleted_WhenTestsWereRetried_AnnotatesTryNumberAndSummaryRetriedCount() + { + var stringBuilderConsole = new StringBuilderConsole(); + var terminalReporter = new TerminalTestReporter(stringBuilderConsole, new TerminalTestReporterOptions + { + AnsiMode = AnsiMode.NoAnsi, + ShowProgress = () => false, + ShowPassedTests = () => true, + ShowAssembly = true, + ShowAssemblyStartAndComplete = true, + }); + + terminalReporter.TestExecutionStarted(DateTimeOffset.MinValue, workerCount: 1, isDiscovery: false, isHelp: false, isRetry: true); + + string assembly = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\repo\Flaky.Tests.dll" : "/repo/Flaky.Tests.dll"; + const string executionId = "exec-flaky"; + + // Attempt 1 fails the test... + terminalReporter.AssemblyRunStarted(assembly, "net9.0", "x64", executionId, instanceId: "inst-1"); + ReportOrchestratorTest(terminalReporter, assembly, executionId, instanceId: "inst-1", testUid: "flaky-1", TestOutcome.Fail); + + // ...attempt 2 (new instance id) retries and passes it. + terminalReporter.AssemblyRunStarted(assembly, "net9.0", "x64", executionId, instanceId: "inst-2"); + ReportOrchestratorTest(terminalReporter, assembly, executionId, instanceId: "inst-2", testUid: "flaky-1", TestOutcome.Passed); + + terminalReporter.AssemblyRunCompleted(executionId, exitCode: 0, outputData: null, errorData: null); + terminalReporter.TestExecutionCompleted(DateTimeOffset.MaxValue, exitCode: 0); + + string output = stringBuilderConsole.Output; + + // 1) Per-test "(try N)" annotation: the failing first attempt is "(try 1)", the passing retry is "(try 2)". + string tryOne = string.Format(CultureInfo.CurrentCulture, TerminalResources.Try, 1); + string tryTwo = string.Format(CultureInfo.CurrentCulture, TerminalResources.Try, 2); + Assert.Contains($"({tryOne})", output); + Assert.Contains($"({tryTwo})", output); + Assert.DoesNotContain($"({string.Format(CultureInfo.CurrentCulture, TerminalResources.Try, 3)})", output); + + // 2) Summary total line carries the "(+1 retried)" suffix. + Assert.Contains($"{TerminalResources.TotalLowercase}: 1 (+1 {TerminalResources.Retried})", output); + + // The retry also surfaces in the per-assembly "(try N) Running tests from" banner. + Assert.Contains($"({tryTwo}) {TerminalResources.RunningTestsFrom}", output); + } + + // Orchestrator discovery (dotnet test --list-tests across N assemblies): each assembly gets a + // "Discovered N tests in assembly - " header with its test names listed, and the run ends with a + // "Discovered M tests in K assemblies." total. The in-process host (ShowAssembly off) keeps its own + // "Test discovery summary: found N test(s)" format, covered by the existing discovery tests. + [TestMethod] + public void AppendTestDiscoverySummary_ForOrchestrator_PrintsPerAssemblyDiscoveredCountsAndTotal() + { + var stringBuilderConsole = new StringBuilderConsole(); + TerminalTestReporter terminalReporter = CreateOrchestratorReporter(stringBuilderConsole); + terminalReporter.TestExecutionStarted(DateTimeOffset.MinValue, workerCount: 2, isDiscovery: true, isHelp: false, isRetry: false); + + string assemblyA = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\repo\A.Tests.dll" : "/repo/A.Tests.dll"; + string assemblyB = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\repo\B.Tests.dll" : "/repo/B.Tests.dll"; + + terminalReporter.AssemblyRunStarted(assemblyA, "net9.0", "x64", executionId: "exec-A", instanceId: "inst-A"); + terminalReporter.AssemblyRunStarted(assemblyB, "net9.0", "x64", executionId: "exec-B", instanceId: "inst-B"); + + terminalReporter.TestDiscovered("exec-A", "A.Test1"); + terminalReporter.TestDiscovered("exec-A", "A.Test2"); + terminalReporter.TestDiscovered("exec-B", "B.Test1"); + + terminalReporter.AssemblyRunCompleted("exec-A"); + terminalReporter.AssemblyRunCompleted("exec-B"); + terminalReporter.TestExecutionCompleted(DateTimeOffset.MaxValue, exitCode: 0); + + string output = stringBuilderConsole.Output; + + // Per-assembly discovered-count headers and the listed test names. + Assert.Contains(string.Format(CultureInfo.CurrentCulture, TerminalResources.DiscoveredTestsInAssembly, 2), output); + Assert.Contains(string.Format(CultureInfo.CurrentCulture, TerminalResources.DiscoveredTestsInAssembly, 1), output); + Assert.Contains("A.Test1", output); + Assert.Contains("B.Test1", output); + + // Run-level total across both assemblies. + Assert.Contains(string.Format(CultureInfo.CurrentCulture, TerminalResources.DiscoveredTestsSummary, 3, 2), output); + + // The in-process-only "Test discovery summary: found N test(s)" wording must NOT appear for the orchestrator. + Assert.DoesNotContain(string.Format(CultureInfo.CurrentCulture, TerminalResources.TestDiscoverySummarySingular, 3), output); + } + [TestMethod] public void AssemblyRunCompleted_WhenKnownAssemblyFails_PrintsExecutableSummary() { var stringBuilderConsole = new StringBuilderConsole(); - var terminalReporter = CreateOrchestratorReporter(stringBuilderConsole); + TerminalTestReporter terminalReporter = CreateOrchestratorReporter(stringBuilderConsole); terminalReporter.TestExecutionStarted(DateTimeOffset.MinValue, workerCount: 1, isDiscovery: false, isHelp: false, isRetry: false); string assembly = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\repo\Failing.dll" : "/repo/Failing.dll"; @@ -1489,7 +1681,7 @@ public void AssemblyRunCompleted_WhenKnownAssemblySucceeds_DoesNotPrintExecutabl // Keep the default ShowAssemblyStartAndComplete: true so the reporter DOES print the per-assembly summary // line. Otherwise a zero-exit run writes nothing at all and the DoesNotContain assertion below passes // vacuously instead of verifying that the executable-summary block is specifically suppressed on success. - var terminalReporter = CreateOrchestratorReporter(stringBuilderConsole); + TerminalTestReporter terminalReporter = CreateOrchestratorReporter(stringBuilderConsole); terminalReporter.TestExecutionStarted(DateTimeOffset.MinValue, workerCount: 1, isDiscovery: false, isHelp: false, isRetry: false); string assembly = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\repo\Passing.dll" : "/repo/Passing.dll"; @@ -1506,11 +1698,40 @@ public void AssemblyRunCompleted_WhenKnownAssemblySucceeds_DoesNotPrintExecutabl Assert.DoesNotContain($"{TerminalResources.ExitCode}:", stringBuilderConsole.Output); } + // Drives the dotnet/sdk acceptance scenario RunMTPProjectThatCrashesWithExitCodeNonZero_ShouldFail_WithSameExitCode: + // an assembly whose tests all pass but whose process exits non-zero (a crash / explicit non-zero exit) is a run + // failure. The run-summary verdict must escalate to "Failed!" even though failed-test count is zero — but only + // AFTER the zero-tests branch, so a legitimately empty project is unaffected (covered separately). + [TestMethod] + public void TestExecutionCompleted_WhenAssemblyExitsNonZeroButTestsPassed_ReportsFailedVerdict() + { + var stringBuilderConsole = new StringBuilderConsole(); + TerminalTestReporter terminalReporter = CreateOrchestratorReporter(stringBuilderConsole); + terminalReporter.TestExecutionStarted(DateTimeOffset.MinValue, workerCount: 1, isDiscovery: false, isHelp: false, isRetry: false); + + string assembly = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\repo\Crashy.dll" : "/repo/Crashy.dll"; + terminalReporter.AssemblyRunStarted(assembly, "net9.0", "x64", "exec-1", "inst-1"); + ReportOrchestratorTest(terminalReporter, assembly, "exec-1", "inst-1", "t-1", TestOutcome.Passed); + + // The process exits 47 even though the single test passed -> Success is false. + terminalReporter.AssemblyRunCompleted("exec-1", exitCode: 47, outputData: null, errorData: null); + terminalReporter.TestExecutionCompleted(DateTimeOffset.MaxValue, exitCode: 47); + + string output = stringBuilderConsole.Output; + + // The run verdict escalates to "Failed!" (not "Passed!") because the assembly process failed. + Assert.Contains($"{TerminalResources.TestRunSummary} {TerminalResources.Failed}!", output); + Assert.DoesNotContain($"{TerminalResources.TestRunSummary} {TerminalResources.Passed}!", output); + + // The summary surfaces the failed-process count on a dedicated "error: 1" line. + Assert.Contains($"{TerminalResources.Error}: 1", output); + } + [TestMethod] public void TestExecutionCompleted_WhenHandshakeFailures_PrintsRecapAndFailsRun() { var stringBuilderConsole = new StringBuilderConsole(); - var terminalReporter = CreateOrchestratorReporter(stringBuilderConsole, showAssemblyStartAndComplete: false); + TerminalTestReporter terminalReporter = CreateOrchestratorReporter(stringBuilderConsole, showAssemblyStartAndComplete: false); terminalReporter.TestExecutionStarted(DateTimeOffset.MinValue, workerCount: 2, isDiscovery: false, isHelp: false, isRetry: false); // Two assemblies fail to handshake (their execution ids were never registered). The assembly paths are not @@ -1528,13 +1749,17 @@ public void TestExecutionCompleted_WhenHandshakeFailures_PrintsRecapAndFailsRun( Assert.Contains(TerminalResources.HandshakeFailuresHeader, output); Assert.Contains("A failed", output); Assert.Contains("B failed", output); + + // With every assembly failing to handshake and zero tests, the summary verdict is "Failed!", not the + // benign "Zero tests ran" (dotnet/sdk#51608). + Assert.Contains($"{TerminalResources.TestRunSummary} {TerminalResources.Failed}!", output); } [TestMethod] public void AssemblyRunStarted_AfterRetry_RendersLatestAttemptCounts() { var stringBuilderConsole = new StringBuilderConsole(); - var terminalReporter = CreateOrchestratorReporter(stringBuilderConsole); + TerminalTestReporter terminalReporter = CreateOrchestratorReporter(stringBuilderConsole); terminalReporter.TestExecutionStarted(DateTimeOffset.MinValue, workerCount: 1, isDiscovery: false, isHelp: false, isRetry: true); string assembly = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\repo\Flaky.dll" : "/repo/Flaky.dll";