Skip to content

feat(analyzers): add FSH0007 behavioral verification of mutation coverage - #103

Merged
samtrion merged 1 commit into
mainfrom
feat/fsh0007-behavioral-verification
Aug 2, 2026
Merged

feat(analyzers): add FSH0007 behavioral verification of mutation coverage#103
samtrion merged 1 commit into
mainfrom
feat/fsh0007-behavioral-verification

Conversation

@samtrion

@samtrion samtrion commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

FrameShift's coverage check (FSH0001) only asks "does any test reach this code?" A test that captures a method reference and asserts IsNotNull() on it clears that check without ever calling the method or verifying its behavior — one test shaped like that cleared 700+ real warnings in a source-generator project without asserting anything.

This PR adds FSH0007, a second-layer check: a mutation point only counts as covered when a test both invokes the member and backs that call with a recognized, non-trivial assertion — not just a bare null check.

  • Test-surface manifest: adds a B line marking behaviorally verified references, additive and backward compatible with manifests written before this change.
  • TestSurfaceCollector: classifies each reference as invoked-vs-bare-method-group, and detects whether a test's reachable code calls a real assertion (AreEqual, IsTrue, Contains, Throws, TUnit's IsEqualTo, etc.) vs. only a trivial null check (AssertionRecognition).
  • ReachabilityClosure.ComputeBehavioral: a second, narrower transitive closure seeded from behaviorally verified references, computed lazily so a compilation that never needs the answer never pays for it.
  • GeneratorDriverBridge: recognizes the CSharpGeneratorDriver.Create(...).RunGenerators(...) test-harness pattern and synthesizes the otherwise-invisible reachability edge to IIncrementalGenerator.Initialize / ISourceGenerator.Initialize+Execute — no more artificial delegate-reference tests needed just to satisfy the analyzer. It's the first implementation of a new IInvocationBridge extension point under TestSurface.Bridges, so a second recognized pattern can be added without touching the collector.

Scope note: this is still static analysis, not execution-based mutation testing. It narrows where the existing heuristics are most obviously wrong (reached-but-never-asserted code); it does not inject a mutant and run the real test suite. That remains a separate, larger effort tracked for follow-up.

Test plan

  • dotnet build FrameShift.slnx — 0 warnings, 0 errors
  • dotnet test (both test projects, all 8 target frameworks) — 30712 test cases, 0 failures
  • New regression test reproduces the exact motivating scenario (method-reference + IsNotNull test) and confirms it no longer counts as covered
  • Dedicated coverage added for ComputeBehavioral, AssertionRecognition, GeneratorDriverBridge, and FSH0007/FSH0006 precedence rules

…rage

Plain reachability lets a test that only captures a method reference and
asserts IsNotNull() clear FSH0001 without ever exercising the method's
behaviour. FSH0007 closes that gap: a mutation point is only treated as
covered when a test both invokes the member and backs that call with a
recognised, non-trivial assertion (AssertionRecognition), not just a bare
null check.

The test-surface manifest gains a 'B' line marking behaviorally verified
references, additive and backward compatible with manifests that predate
it. TestSurfaceCollector classifies each reference as invoked-vs-bare and
tracks whether a test's reachable code calls a real assertion.
ReachabilityClosure.ComputeBehavioral seeds a second, narrower closure from
those references, computed lazily so a compilation where it is never
needed never pays for it.

GeneratorDriverBridge recognises the CSharpGeneratorDriver.Create(...)
.RunGenerators(...) test-harness pattern and synthesizes the otherwise
invisible reachability edge to IIncrementalGenerator.Initialize /
ISourceGenerator.Initialize+Execute, so a source-generator test no longer
needs an artificial delegate-reference just to satisfy the analyzer. It is
the first implementation of the new IInvocationBridge extension point
under TestSurface.Bridges, so a second recognised pattern can be added
without collector changes.

Static-analysis based, not execution based: FSH0007 narrows where the
existing heuristics are most obviously wrong, it does not run mutants
against the real test suite.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • state:ready for merge

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 236f10ac-7833-415d-9a38-174f5453d02e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.70552% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.36%. Comparing base (1f8ab51) to head (5292146).

Files with missing lines Patch % Lines
...Shift/TestSurface/Bridges/GeneratorDriverBridge.cs 88.00% 5 Missing and 4 partials ⚠️
...lve.FrameShift/TestSurface/TestSurfaceCollector.cs 94.23% 1 Missing and 2 partials ⚠️
...olve.FrameShift/TestSurface/TestSurfaceManifest.cs 95.65% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #103      +/-   ##
==========================================
+ Coverage   95.32%   95.36%   +0.03%     
==========================================
  Files          91       93       +2     
  Lines        5928     6233     +305     
  Branches     1295     1340      +45     
==========================================
+ Hits         5651     5944     +293     
- Misses        122      128       +6     
- Partials      155      161       +6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@samtrion
samtrion merged commit 4ae3c20 into main Aug 2, 2026
12 checks passed
@samtrion
samtrion deleted the feat/fsh0007-behavioral-verification branch August 2, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant