| name | test-gap-analysis |
| description | Pseudo-mutation analysis for behavioral blind spots: determine whether existing tests would catch meaningful caller-visible production changes, identify survivors or untested outcomes, and optionally close verified gaps with focused tests. Use for behavioral gaps and missing edge cases. Use coverage-analysis when available for project-wide coverage arithmetic and test-anti-patterns when available for broad test-quality smells. |
| license | MIT |
Test Gap Analysis
Answer one question: which caller-visible production behaviors could change without an existing test failing? Mutation reasoning is a probe, not the goal. Inventory public outcomes first, then verify only credible gaps.
Dapper-FluentMap integration: preserve public compatibility and use the repository's existing test layers. Prefer test/Dapper.FluentMap.Tests for focused core behavior, provider/integration suites for materialization behavior, Roslyn tests for analyzers/generators, and eng/consumer-smoke for package-consumer behavior. Do not mutate global Dapper/FluentMap state without restoring it.
Decision flow
1. Set scope
Discover production and test files from Dapper.FluentMap.slnx and the existing test layout. Keep a focused request focused.
| Request | Action |
|---|
| One component or named risk | Inventory every high-risk public outcome in scope; do not edit production code unless verification was requested |
| General small-component review | Inventory distinct outcomes and report caller-visible gaps from source/assertion mapping |
| Explicit survivor verification | Execute one representative observable candidate for each distinct high-risk outcome under verification |
| Explicit exhaustive audit | Read references/mutation-catalog.md and classify all meaningful candidates |
| Add tests to an existing suite | Analyze first; add tests only for verified survivors or demonstrated no-coverage outcomes |
2. Establish one baseline
Run the narrowest existing test command once and confirm tests actually executed. For core behavior, normally start with:
dotnet test ./test/Dapper.FluentMap.Tests/Dapper.FluentMap.Tests.csproj --configuration Release
If the suite cannot run, continue statically and label executable mutation candidates unverified.
3. Inventory public outcomes
For each public entry point, map:
- input partitions and guard boundaries;
- returns/results/exceptions/state transitions/side effects;
- mapping precedence and fallback behavior;
- case sensitivity, duplicate registration, conventions and caches when relevant;
- Dapper materialization or Dommel behavior only through real caller-visible outcomes;
- analyzer/generator diagnostics and generated output when relevant.
Use:
public input/sequence -> expected outcome -> existing assertion -> gap
One asserted field does not cover another. Unit metadata tests do not prove end-to-end Dapper materialization.
4. Admit only observable candidates
Before reporting a candidate, replay it against existing asserted inputs. If an assertion observes the changed result, it is Likely killed and not a gap.
For survivors, state:
witness -> original observation -> mutant observation
Exclude generated code, formatting/logging-only changes unless contractual, non-compiling edits, equivalent mutations, impossible domain values, trivial forwarding members, and private representation changes callers cannot distinguish.
5. Rank and classify
Prioritize:
- public compatibility, mapping correctness, package-consumer behavior, data correctness and error semantics;
- wholly unasserted public outcomes;
- exact boundaries/precedence/case behavior reached only by weak assertions;
- alternate variants of already-protected behavior.
Use these labels:
| Result | Meaning |
|---|
| Likely killed | An existing assertion observes the changed outcome |
| Candidate survivor (unverified) | Observable change appears unasserted; not executed |
| Survived | Exact observable mutation executed and tests stayed green |
| No coverage | No test reaches the public outcome |
| Equivalent | No public observation changes; omit from findings |
Verdict: Strong, Mixed, or Weak.
6. Verify safely when requested
- Apply one temporary candidate and confirm the diff changes exactly one intended expression.
- Run the narrowest covering tests.
- Green = Survived; red = Killed, for that edit only.
- Revert immediately and confirm the source baseline is clean.
- Never commit temporary mutations.
- Restore global FluentMap/Dapper state in tests that alter it.
7. Close gaps only when requested
- Add focused behavior tests only for demonstrated gaps.
- Prefer tests that protect a caller-visible contract over tests that merely inflate coverage.
- Use integration/provider tests when the risk concerns actual Dapper materialization.
- Use package/consumer-smoke validation when the risk concerns package identity, analyzers/generators, trimming, or installation.
Output contract
For focused analysis return one-line verdict, a short strengths sentence, then one compact row per actionable gap:
| Risk | Public outcome | Change | Result/evidence | Smallest test |
|---|
Every gap needs a distinguishing witness and a concrete smallest test.
Reliability rules
- A passing test that does not assert the changed outcome does not kill a mutation.
- Coverage is per behavior partition, not merely per executed line.
- Never recommend a redundant test for behavior already protected.
AGENTS.md, repository compatibility rules, and deterministic validation prevail over this skill.