@@ -128,7 +128,162 @@ end
128128Every option is documented in [docs/Configuration.md](docs/Configuration.md),
129129including criteria, filters, groups, profiles, and thresholds.
130130
131- Measuring coverage in production to find dead code is its own mode with its
132- own document, [docs/Production.md](docs/Production.md): a live process
133- accumulates what real traffic executes, and `simplecov dead-code`, the HTML
134- report, and `coverage.json` cross that with what the tests cover.
131+ ## Tracking which test covers each line
132+
133+ Coverage normally tells you whether a line ran, not what ran it. `track_tests`
134+ records the other half of the story:
135+
136+ ```ruby
137+ SimpleCov.start do
138+ track_tests
139+ end
140+ ```
141+
142+ RSpec examples and Minitest tests are wrapped automatically. In the HTML
143+ report, covered lines that no test executed (they only ran at load time, or in
144+ suite setup) drain to a distinct tint, so coverage that merely *loads* code
145+ stops passing for coverage that *tests* it, and clicking a line' s badge lists
146+ the tests that cover it. The same recording answers from the terminal:
147+
148+ ` ` ` sh
149+ $ simplecov tests lib/simplecov/result.rb:42
150+ spec/result_spec.rb:42
151+ ` ` `
152+
153+ The output is one test id per line and nothing else , so it pipes straight into
154+ a runner. ` simplecov tests --redundant` inverts the question, listing the
155+ tests whose covered lines other tests also cover, which is where a
156+ [test - pruning session](docs/ Redundant_Tests .md) starts. Recording has a real
157+ cost, which is why it' s opt-in and comes with levers to control it. See
158+ [the configuration docs](docs/Configuration.md#tracking-which-test-covers-each-line).
159+
160+ ## Finding dead code in production
161+
162+ SimpleCov can also measure production code usage, the surest way to find
163+ dead code. The old trick was to plant a log line in a suspect method and
164+ watch production for a while. Oneshot coverage runs that experiment for
165+ every line at once: a line reports its first execution and nothing after,
166+ so a live process records what real traffic uses with the least possible
167+ impact on performance. `simplecov dead-code` then crosses the recording
168+ with the test report and turns it into insight you can act on. Code
169+ neither tests nor traffic touch is safe to delete, and code production
170+ runs but tests skip is the most valuable test you haven' t written. The
171+ HTML report and ` coverage.json` include the same production data. See
172+ [docs/ Production .md](docs/ Production .md) for more details on why and how
173+ to set it up.
174+
175+ # # Coverage of just your change
176+
177+ An overall number moves slowly on a mature codebase, but " is the code in this
178+ change tested?" has a crisp answer the day you ask it. ` simplecov patch` reads
179+ the git diff against a base ref and scores only the lines you touched:
180+
181+ ` ` ` sh
182+ $ simplecov patch --base main --minimum 100
183+ 88.00% (22/25) lines lib/simplecov/cli/patch.rb missing 41-43
184+ 100.00% (4/4) lines lib/simplecov/result.rb
185+ Patch coverage: 89.66% (26/29) lines
186+ ` ` `
187+
188+ ` --minimum` turns it into a gate, so a project that can' t lift its overall
189+ number in one pull request can still require that everything it adds is
190+ covered. The flip side is `simplecov affected`, which uses a `track_tests`
191+ recording to select the tests that touch your changed code and hand them to
192+ the runner, falling back (loudly) to the full suite whenever the map can' t be
193+ trusted:
194+
195+ ` ` ` sh
196+ $ simplecov affected --base main --run bundle exec rspec
197+ ` ` `
198+
199+ Both commands are documented in [the CLI docs](docs/ CLI .md).
200+
201+ # # Covering views
202+
203+ View templates execute real logic, and now they can be part of the report.
204+ ` cover_views` brings ERB , Haml , and Slim templates in , measured through eval
205+ coverage (CRuby 3.2 + ):
206+
207+ ` ` ` ruby
208+ SimpleCov.start 'rails' do
209+ cover_views
210+ end
211+ ` ` `
212+
213+ Templates are ordinary files in the report, highlighted in their own language
214+ and grouped under Views by the ` rails` profile, and a template no test renders
215+ shows up at 0 % instead of being quietly missing. Expect your overall number to
216+ drop the first time you turn this on. That ' s the point. See
217+ [view coverage](docs/Configuration.md#view-coverage).
218+
219+ ## A consistent configuration grammar
220+
221+ The configuration API was redesigned around a small set of consistent verbs.
222+ Formatters are picked by name, thresholds live in a per-criterion `coverage`
223+ block where scope is a uniform `per:` argument, and misses can be capped as
224+ absolute counts rather than ratios:
225+
226+ ```ruby
227+ SimpleCov.start do
228+ formats :html, :json
229+
230+ coverage :line do
231+ minimum 90
232+ minimum 100, per: "lib/simplecov/result.rb"
233+ maximum_missed 5, per: :file # no file may carry more than 5 uncovered lines
234+ end
235+
236+ coverage :branch, minimum: 80, ignore: :implicit_else
237+ end
238+ ```
239+
240+ Everything you' re using today keeps working. Legacy spellings warn and name
241+ their replacement, and once you' ve migrated, `deprecations :raise` turns any
242+ old spelling that creeps back in into an error. The
243+ [migration map](docs/Configuration.md#migrating-from-the-legacy-configuration-api)
244+ has the full before and after.
245+
246+ ## Per-file ratchets and coverage history
247+
248+ On a legacy codebase, one per-file minimum does nothing useful: set it to what
249+ the worst file scores and every other file is allowed to sink to that level.
250+ `simplecov ratchet` writes a checked-in baseline instead, giving each file its
251+ own floor at the coverage it has already reached:
252+
253+ ```sh
254+ $ simplecov ratchet
255+ simplecov ratchet: wrote .simplecov_baseline.yml (3 tightened, 1 pruned, 148 unchanged)
256+ ```
257+
258+ Floors only ever tighten, so touching a legacy file drags its coverage upward
259+ and it can never slide back. Think `.rubocop_todo.yml`, applied to coverage.
260+ To ratchet automatically at the end of every run, add the baseline formatter
261+ with `formats :html, :baseline`.
262+
263+ Alongside the floors, every successful run now appends to
264+ `coverage/.history.json`, so you have a recorded trend rather than just the
265+ last number. `simplecov history` draws it as sparklines in the terminal, and
266+ `drop_baseline :median` judges coverage drops against the recorded median
267+ instead of whatever the previous run happened to score. See
268+ [the baseline](docs/Configuration.md#per-file-baseline-ratchet) and
269+ [run history](docs/Configuration.md#run-history) docs.
270+
271+ ## More from the command line
272+
273+ The `simplecov` CLI has grown from a report opener into a toolbelt. A few
274+ favorites:
275+
276+ ```sh
277+ $ simplecov watch bundle exec rspec # re-run on save, live-reload the served report
278+ $ simplecov show lib/foo.rb # annotated source in the terminal
279+ $ simplecov status # is this report fresh, and for which commit?
280+ $ simplecov uncovered --missing # worst files, with the exact line ranges to test
281+ $ simplecov badge --output badge.svg # a shields.io-style SVG, no badge service needed
282+ ```
283+
284+ `watch` deserves the highlight: with a `track_tests` recording in the report,
285+ a save re-runs only the tests that touch the files you changed, which turns
286+ the report into something you keep open while writing the test. There is also
287+ shell tab completion (`simplecov completions fish|bash|zsh`), a man page, and
288+ a real `--help` on every command. The full tour is in
289+ [docs/CLI.md](docs/CLI.md).
0 commit comments