Overview
The file src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs has grown to 990 lines, making it harder to navigate and maintain. The class is already declared as partial, so the natural refactoring is to split it into multiple focused partial class files within the same directory.
Current State
- File:
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs
- Size: 990 lines
- Language: C#
- Note: The class is already
internal sealed partial class TerminalTestReporter, so no structural changes to the type are needed—only file-level splits.
Structural Analysis
The file contains the following logical groups:
- Fields, constructor, events (lines ~1–123): Private fields, constants, events for progress update notifications, and the public constructor.
- Lifecycle methods (lines ~124–198 and ~708–829):
TestExecutionStarted, AssemblyRunStarted, AssemblyRunCompleted, TestExecutionCompleted, GetOrAddAssemblyRun.
- Summary rendering (lines ~199–330 and ~906–970):
AppendTestRunSummary, AppendTestDiscoverySummary, PrintOutOfProcessArtifacts.
- Test completion handling (lines ~331–494):
TestCompleted (public + private overloads), GetShowPassedTests, RenderTestCompleted.
- Exception/output formatting (lines ~495–609):
FormatInnerExceptions, FormatErrorMessage, FormatExpectedAndActual, FormatStackTrace, FormatStandardAndErrorOutput, GetStringFromIndexOrDefault.
- Text/stack/duration formatting helpers (lines ~610–829):
AppendAssemblyLinkTargetFrameworkAndArchitecture, AppendStackFrame, AppendIndentedLine, MakeControlCharactersVisible, CreateControlCharSearchValues/CreateControlCharArray, AppendLongDuration.
- Messaging and artifacts (lines ~830–905):
WriteMessage, WriteErrorMessage, WriteWarningMessage, ArtifactAdded, StartCancelling, Dispose.
- Discovery and progress (lines ~884–990):
TestDiscovered, AppendTestDiscoverySummary, TestInProgress.
Refactoring Strategy
Proposed File Splits
Since the class is already partial, each new file simply moves methods into a separate partial class file:
-
TerminalTestReporter.cs (core — keep as-is but slimmed)
- Contents: Fields, constructor, events,
Dispose, StartCancelling, ArtifactAdded, PrintOutOfProcessArtifacts
- Responsibility: Core state, initialization, and simple public lifecycle entry points
-
TerminalTestReporter.Lifecycle.cs
- Contents:
TestExecutionStarted, AssemblyRunStarted, GetOrAddAssemblyRun, AssemblyRunCompleted, TestExecutionCompleted
- Responsibility: Run lifecycle management (start/stop events for the whole test run and per-assembly)
-
TerminalTestReporter.TestCompletion.cs
- Contents:
TestCompleted (both overloads), GetShowPassedTests, RenderTestCompleted
- Responsibility: Processing and rendering individual test results
-
TerminalTestReporter.Summary.cs
- Contents:
AppendTestRunSummary, AppendTestDiscoverySummary, TestDiscovered
- Responsibility: End-of-run and discovery summary rendering
-
TerminalTestReporter.Formatting.cs
- Contents:
FormatInnerExceptions, FormatErrorMessage, FormatExpectedAndActual, FormatStackTrace, FormatStandardAndErrorOutput, GetStringFromIndexOrDefault, AppendAssemblyLinkTargetFrameworkAndArchitecture, AppendStackFrame, AppendIndentedLine, MakeControlCharactersVisible, CreateControlCharSearchValues/CreateControlCharArray, AppendLongDuration
- Responsibility: All formatting/rendering helpers for exceptions, stack traces, output, and duration display
-
TerminalTestReporter.Messaging.cs
- Contents:
WriteMessage, WriteErrorMessage, WriteWarningMessage, TestInProgress
- Responsibility: General message writing and in-progress test progress updates
Implementation Guidelines
- Preserve Behavior: All existing functionality must work identically after the split
- No API changes: The class remains
internal sealed partial; no public API surface changes
- One file at a time: Split one group at a time and verify the build succeeds after each step
- No new usings needed: All
using directives should stay in the main file (or be duplicated in each partial file if the compiler requires it)
- Test After Each Split: Run the test suite after each incremental change — focus on
Microsoft.Testing.Platform.UnitTests and acceptance tests
Acceptance Criteria
Priority: Medium
Effort: Small (the class is already partial; this is purely mechanical file splitting)
Expected Impact: Improved code navigability, easier targeted reviews, reduced merge conflicts on this hot file
Generated by Daily File Diet · ● 345.2K · ◷
Overview
The file
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cshas grown to 990 lines, making it harder to navigate and maintain. The class is already declared aspartial, so the natural refactoring is to split it into multiple focused partial class files within the same directory.Current State
src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.csinternal sealed partial class TerminalTestReporter, so no structural changes to the type are needed—only file-level splits.Structural Analysis
The file contains the following logical groups:
TestExecutionStarted,AssemblyRunStarted,AssemblyRunCompleted,TestExecutionCompleted,GetOrAddAssemblyRun.AppendTestRunSummary,AppendTestDiscoverySummary,PrintOutOfProcessArtifacts.TestCompleted(public + private overloads),GetShowPassedTests,RenderTestCompleted.FormatInnerExceptions,FormatErrorMessage,FormatExpectedAndActual,FormatStackTrace,FormatStandardAndErrorOutput,GetStringFromIndexOrDefault.AppendAssemblyLinkTargetFrameworkAndArchitecture,AppendStackFrame,AppendIndentedLine,MakeControlCharactersVisible,CreateControlCharSearchValues/CreateControlCharArray,AppendLongDuration.WriteMessage,WriteErrorMessage,WriteWarningMessage,ArtifactAdded,StartCancelling,Dispose.TestDiscovered,AppendTestDiscoverySummary,TestInProgress.Refactoring Strategy
Proposed File Splits
Since the class is already
partial, each new file simply moves methods into a separate partial class file:TerminalTestReporter.cs(core — keep as-is but slimmed)Dispose,StartCancelling,ArtifactAdded,PrintOutOfProcessArtifactsTerminalTestReporter.Lifecycle.csTestExecutionStarted,AssemblyRunStarted,GetOrAddAssemblyRun,AssemblyRunCompleted,TestExecutionCompletedTerminalTestReporter.TestCompletion.csTestCompleted(both overloads),GetShowPassedTests,RenderTestCompletedTerminalTestReporter.Summary.csAppendTestRunSummary,AppendTestDiscoverySummary,TestDiscoveredTerminalTestReporter.Formatting.csFormatInnerExceptions,FormatErrorMessage,FormatExpectedAndActual,FormatStackTrace,FormatStandardAndErrorOutput,GetStringFromIndexOrDefault,AppendAssemblyLinkTargetFrameworkAndArchitecture,AppendStackFrame,AppendIndentedLine,MakeControlCharactersVisible,CreateControlCharSearchValues/CreateControlCharArray,AppendLongDurationTerminalTestReporter.Messaging.csWriteMessage,WriteErrorMessage,WriteWarningMessage,TestInProgressImplementation Guidelines
internal sealed partial; no public API surface changesusingdirectives should stay in the main file (or be duplicated in each partial file if the compiler requires it)Microsoft.Testing.Platform.UnitTestsand acceptance testsAcceptance Criteria
TerminalTestReporter.csis split into focused partial class filesTerminalTestReporter.csis also reduced to under 300 linesdotnet test test/UnitTests/Microsoft.Testing.Platform.UnitTests/Microsoft.Testing.Platform.UnitTests.csproj)Priority: Medium
Effort: Small (the class is already
partial; this is purely mechanical file splitting)Expected Impact: Improved code navigability, easier targeted reviews, reduced merge conflicts on this hot file