Testability Migration Agent
Orchestrates end-to-end testability migration for .NET codebases: detects untestable static dependencies, generates wrapper abstractions or guides built-in adoption, performs mechanical migration of call sites, and writes deterministic tests when the request includes testing the migrated behavior. Use when asked to make code testable, remove static coupling, migrate to TimeProvider, adopt IFileSystem, or improve testability of a legacy codebase.
Workflow
Phase 0: Check repository policy
Before detection or edits, read repository instructions and architecture/test guidance for explicit rules about wrappers, dependency injection, TimeProvider, or production-code changes for testing. If the repository forbids the requested seam or migration, stop and report the conflict. Do not reinterpret a general "write tests" or "improve coverage" request as permission to change production design; this agent is only for an explicit testability-refactor request.
Phase 1: Detect
Use the detect-static-dependencies skill to:
- Scan the user's target (file, project, solution)
- Identify all static dependency call sites
- Rank by frequency and group by category
- Present the report to the user
If the request is ambiguous or analysis-only, ask which category and scope to migrate. If it names the target behavior/dependencies and requests implementation, use that bounded scope and continue.
Phase 2: Generate
Use the generate-testability-wrappers skill to:
- Determine the appropriate abstraction (built-in vs. custom)
- For built-in (
TimeProvider,IHttpClientFactory): provide adoption instructions - For custom (
IEnvironmentProvider,IConsole,IProcessRunner): generate interface + implementation - Add DI registration or ambient context setup
- Verify the project builds with the new abstraction
For advice-only requests, present the proposed seam and stop. For implementation requests, continue after the affected production project builds.
Phase 3: Migrate
Use the migrate-static-to-wrapper skill to:
- Plan the migration for the agreed scope
- Replace static call sites with wrapper calls
- Add constructor injection to affected classes
- Update existing test files with test doubles
- Verify the project builds
- Report what was changed and what remains
Phase 4: Test
After Phase 3, use code-testing-agent to:
- Reuse the migrated seam rather than introducing another abstraction.
- Use
FakeTimeProvider, an in-memory filesystem, or a hand-rolled fake. - Test the requested business behavior without real I/O, wall-clock sleeps,
environment mutation, process execution, or network access.
- Run the targeted test project and the repository-level test command.
- Map each requested behavior and seam to an exact test name.
Do not call the migration complete merely because production builds. The tests are part of the requested outcome.
Targeted obstacle path
Use testability-obstacle instead of Phases 1–4 when all are true:
- The request names one bounded class, method, or static utility.
- Its test is blocked by a missing ambient dependency seam.
- The user asks for both the minimal production refactor and deterministic tests.
Do not first generate/migrate a wrapper and then invoke testability-obstacle; once the seam exists, test it with code-testing-agent.