Skip to content

Refactor: Split TestMethodInfo.cs (1113 lines) into focused partial classes #7966

@Evangelink

Description

@Evangelink

Overview

The file src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodInfo.cs has grown to 1113 lines, making it harder to navigate and maintain. This task involves refactoring it into smaller, more focused files using C# partial class syntax.

Current State

  • File: src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodInfo.cs
  • Size: 1113 lines
  • Language: C#
Structural Analysis

The file contains a single TestMethodInfo class (implementing ITestMethod) with the following distinct concern groups:

Lines Members Responsibility
~40–126 Constructor, properties, GetAllAttributes, GetAttributes<T> Core identity and attribute access
~127–249 InvokeAsync, SetArguments, ResolveArguments Public entry point and argument resolution
~250–329 GetTestTimeout, GetTestMethodAttribute, GetRetryAttribute, ThrowMultipleAttributesException Configuration/attribute lookup
~330–597 ExecuteInternalAsync, ExecuteInternalWithTimeoutAsync, GetRealException, HandleMethodException Core test execution and exception handling
~598–703 RunTestCleanupMethodAsync, HasCleanupsToInvoke Cleanup lifecycle
~705–957 RunTestInitializeMethodAsync, InvokeInitializeMethodAsync, InvokeGlobalInitializeMethodAsync, InvokeCleanupMethodAsync, InvokeGlobalCleanupMethodAsync, CaptureExecutionContextAfterFixtureIfNeeded Initialize/cleanup method invocation
~959–1113 SetTestContext, CreateTestClassInstance Context and instance setup

Refactoring Strategy

Since TestMethodInfo is a single class, the recommended approach is to split it into partial class files, keeping the class name and access modifiers identical across all files:

Proposed File Splits

  1. TestMethodInfo.cs (keep, trimmed down to ~150 lines)

    • Contents: constructor, fields, all properties, GetAllAttributes, GetAttributes<T>
    • Responsibility: Core class identity, public ITestMethod surface, and attribute access
  2. TestMethodInfo.Arguments.cs (new, ~85 lines)

    • Contents: SetArguments, ResolveArguments
    • Responsibility: Parsing and resolving data-driven test arguments
  3. TestMethodInfo.Configuration.cs (new, ~80 lines)

    • Contents: GetTestTimeout, GetTestMethodAttribute, GetRetryAttribute, ThrowMultipleAttributesException
    • Responsibility: Reading and validating test configuration attributes
  4. TestMethodInfo.Execution.cs (new, ~270 lines)

    • Contents: InvokeAsync, ExecuteInternalAsync, ExecuteInternalWithTimeoutAsync, GetRealException, HandleMethodException
    • Responsibility: Orchestrating the full test run and translating exceptions to TestResult
  5. TestMethodInfo.Lifecycle.cs (new, ~350 lines)

    • Contents: RunTestInitializeMethodAsync, InvokeInitializeMethodAsync, InvokeGlobalInitializeMethodAsync, RunTestCleanupMethodAsync, InvokeCleanupMethodAsync, InvokeGlobalCleanupMethodAsync, HasCleanupsToInvoke, CaptureExecutionContextAfterFixtureIfNeeded
    • Responsibility: Invoking TestInitialize / TestCleanup methods and managing execution context capture
  6. TestMethodInfo.Context.cs (new, ~60 lines)

    • Contents: SetTestContext, CreateTestClassInstance
    • Responsibility: Creating the test class instance and injecting TestContext

Implementation Guidelines

  1. Preserve Behavior: All existing functionality must work identically after the split
  2. Maintain Public API: Keep all exported/public symbols accessible with the same names — TestMethodInfo remains a single type
  3. Use partial class: Add partial keyword to TestMethodInfo and each new file — no new types introduced
  4. Test After Each Split: Run the test suite after each incremental move to catch regressions early
  5. One File at a Time: Split one concern group at a time to keep diffs reviewable

Acceptance Criteria

  • TestMethodInfo.cs is split into focused partial class files
  • Each new file is under 300 lines
  • All tests pass after refactoring
  • No breaking changes to the public or internal API
  • File naming follows the TypeName.Concern.cs convention already used elsewhere in the repo

Priority: Medium
Effort: Small — the class is self-contained; splitting into partial files requires no API changes and minimal dependency updates
Expected Impact: Improved code navigability, easier targeted testing, reduced merge conflicts on the execution pipeline

Generated by Daily File Diet · ● 335.6K ·

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions