Tester Architecture Refactor Plan
Overview
- Migrate the bespoke CLI-based test harness to a first-class
.NETtest project namedTesterthat executes underdotnet test. - Reduce end-to-end runtime by embracing framework-managed parallelism and shared fixtures.
- Preserve existing workflow coverage (CLI init/build/publish/watch/test) while improving observability and tooling integration.
Goals
- Adopt xUnit as the canonical framework for all automated tests.
- Enable execution via
dotnet testlocally and in CI without compatibility shims. - Maintain the current quick/full suite split through standard trait filtering.
- Leverage fixtures to minimize redundant workspace initialization and dependency installs.
- Produce test outputs compatible with IDE tooling (VS, Rider) and common CI reporters.
Non-Goals
- Rewriting the CLI workflows themselves.
- Introducing new workflow scenarios beyond today’s coverage.
- Building backwards compatibility layers for the legacy runner.
Background
The existing Tests project (to be replaced by Tester) is an executable that orchestrates custom ITestSuite/ITestCase implementations. It depends on shared helpers (WorkspaceManager, ProcessRunner, CLI wrappers) to bootstrap seed workspaces and run external commands. While it offers rich coverage, the custom harness:
- Cannot be invoked via
dotnet test, limiting IDE tooling and CI integration. - Serializes many scenarios, inflating runtime.
- Requires bespoke reporting/diagnostics plumbing.
The migration will streamline execution by leaning on xUnit primitives while reusing the domain-specific helpers that interact with the CLI.
Design Tenets
- Reuse over rewrite: Keep CLI/process helper code; wrap existing scenarios in xUnit facts.
- Parallel where safe: Organize tests into xUnit collections to isolate stateful workflows and allow read-only checks to run concurrently.
- Fixture-first setup: Cache expensive setup (seed workspace, dependency install) in collection fixtures; ensure deterministic cleanup.
- Lean assertions: Replace bespoke assertions with xUnit equivalents except where domain-specific helpers add clarity.
Target Architecture
- Replace the executable project with
Tester/Tester.csproj, configured withMicrosoft.NET.Test.Sdk, xUnit packages, and noMainentry point. - Introduce:
CollectionFixturesfor seed workspace preparation and shared CLI context.Traitconstants mirroringTestCategory(Quick,Full).- Helper adapters (
WorkflowFactbase class) to bridge currentITestCaselogic into[Fact]methods.
- Delete legacy abstractions (
ITestSuite,ITestRunner,TestOutputManager) once all suites are migrated. - Update scripts (
utilities/format-build.sh, CI definitions) to calldotnet test.
Phased Migration
Phase 1: Foundations
- Add xUnit dependencies and test SDK configuration within the
Testerproject. - Implement shared fixtures for seed workspace / CLI helpers.
- Port the Init workflow tests as a spike to validate the structure.
Phase 2: Workflow Migration
- Port remaining workflow suites (Build, Publish, Watch, Help, Add, Framework packages, Package installers) into
Tester. - Introduce
[Trait]attributes and ensure quick/full toggles respect current behavior. - Remove corresponding legacy suite classes after each migration.
Phase 3: Cleanup & Tooling
- Remove unused infrastructure (legacy
Testsrunner entry point and supporting wiring) after theTestermigration. - Update developer docs (
README, orchestrator testing guide, internal runbooks) to referenceTesteranddotnet test. - Adjust CI pipelines and
format-build.shto run the new test command.
Phase 4: Performance Optimization
- Enable xUnit parallelization for non-mutating collections.
- Tune workspace copying/fixtures (e.g., node_modules symlink strategy) to minimize setup time.
- Add diagnostics/tracing to surface slow tests and refine collection boundaries.
Risks & Mitigations
- Workspace contention: Mutating workflows could interfere when parallelized. Mitigate with collection scoping and defensive copy/symlink strategies.
- Timeout tuning: CLI commands run longer under load; establish clear defaults and per-test overrides.
- CI environment parity: Ensure fixtures handle Linux/macOS differences (symlink support) gracefully.
Success Criteria
dotnet testsucceeds locally without custom flags by targeting theTesterproject.- CI pipelines adopt the new command and complete within agreed SLAs.
- Developers can filter quick/full suites via traits.
- Legacy harness code is fully removed with no loss of scenario coverage.
Resolved Questions
- Test result artifacts: Tester runs in CI will emit both TRX and Markdown summaries (via
dotnet test --logger trxand a custom Markdown converter) and upload them as pipeline artifacts for downstream analytics. - Coverage integration: We will wire Coverlet into Tester once the migration is complete, collecting coverage for
CLIandEngineassemblies with an initial soft threshold (warning-only) to keep the signal actionable without blocking commits. - Upcoming workflow fixtures: Framework package release tests from Phase 6 and future CLI orchestration suites (e.g., backend package smoke tests) will get dedicated collection fixtures to isolate their workspace mutations while allowing lighter suites to run in parallel.