Skip to content

Refactor: Split TerminalTestReporter.cs (990 lines) into focused partial class files #8137

@Evangelink

Description

@Evangelink

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:

  1. Fields, constructor, events (lines ~1–123): Private fields, constants, events for progress update notifications, and the public constructor.
  2. Lifecycle methods (lines ~124–198 and ~708–829): TestExecutionStarted, AssemblyRunStarted, AssemblyRunCompleted, TestExecutionCompleted, GetOrAddAssemblyRun.
  3. Summary rendering (lines ~199–330 and ~906–970): AppendTestRunSummary, AppendTestDiscoverySummary, PrintOutOfProcessArtifacts.
  4. Test completion handling (lines ~331–494): TestCompleted (public + private overloads), GetShowPassedTests, RenderTestCompleted.
  5. Exception/output formatting (lines ~495–609): FormatInnerExceptions, FormatErrorMessage, FormatExpectedAndActual, FormatStackTrace, FormatStandardAndErrorOutput, GetStringFromIndexOrDefault.
  6. Text/stack/duration formatting helpers (lines ~610–829): AppendAssemblyLinkTargetFrameworkAndArchitecture, AppendStackFrame, AppendIndentedLine, MakeControlCharactersVisible, CreateControlCharSearchValues/CreateControlCharArray, AppendLongDuration.
  7. Messaging and artifacts (lines ~830–905): WriteMessage, WriteErrorMessage, WriteWarningMessage, ArtifactAdded, StartCancelling, Dispose.
  8. 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:

  1. 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
  2. TerminalTestReporter.Lifecycle.cs

    • Contents: TestExecutionStarted, AssemblyRunStarted, GetOrAddAssemblyRun, AssemblyRunCompleted, TestExecutionCompleted
    • Responsibility: Run lifecycle management (start/stop events for the whole test run and per-assembly)
  3. TerminalTestReporter.TestCompletion.cs

    • Contents: TestCompleted (both overloads), GetShowPassedTests, RenderTestCompleted
    • Responsibility: Processing and rendering individual test results
  4. TerminalTestReporter.Summary.cs

    • Contents: AppendTestRunSummary, AppendTestDiscoverySummary, TestDiscovered
    • Responsibility: End-of-run and discovery summary rendering
  5. 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
  6. TerminalTestReporter.Messaging.cs

    • Contents: WriteMessage, WriteErrorMessage, WriteWarningMessage, TestInProgress
    • Responsibility: General message writing and in-progress test progress updates

Implementation Guidelines

  1. Preserve Behavior: All existing functionality must work identically after the split
  2. No API changes: The class remains internal sealed partial; no public API surface changes
  3. One file at a time: Split one group at a time and verify the build succeeds after each step
  4. 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)
  5. Test After Each Split: Run the test suite after each incremental change — focus on Microsoft.Testing.Platform.UnitTests and acceptance tests

Acceptance Criteria

  • TerminalTestReporter.cs is split into focused partial class files
  • Each new file is under 300 lines
  • The main TerminalTestReporter.cs is also reduced to under 300 lines
  • All tests pass after refactoring (dotnet test test/UnitTests/Microsoft.Testing.Platform.UnitTests/Microsoft.Testing.Platform.UnitTests.csproj)
  • No breaking changes to public or internal API
  • No behavioral changes

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 ·

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions