Build1 distinct publisher3 min readUpdated
A hand-written mutation survived all 20 generated pytest tests on a small CSV parser. Coverage counted lines executed; nothing in the suite checked the behaviour.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
A developer with an untested Python CSV parser asked a free model for a pytest suite, got 20 tests back, and measured 94% line coverage [1][4][5]. He then changed one boolean condition in the source by hand, and every test still passed [8].
The library is about as plain as shipping code gets: open a CSV with DictReader, keep rows where both `Course` and `Time` are present, parse the time string, return a list of dicts [1][6]. `parse_time` returns a time object, or `None` when `strptime` raises `ValueError` [7]. The prompt asked for normal cases, missing values and invalid dates, and for test code only [3]. Under pytest and coverage.py the report came back at 94%, with line 12, the `row.get('Course')` check, as the only miss [5].
The mutation was one clause: `row.get('Course')` became `row.get('Course') or True`, which makes half the guard vacuous [8]. The suite passed and coverage still read 94% [8]. The reason is not subtle. None of the generated tests fed in a row without a `Course` key; they exercised a missing `Time` but never a missing `Course`, and every fixture carried a `Course` column [9]. With the mutant in place, any row missing a course name flows straight into the output [10]. A second mutation did get caught: making `parse_time` return `datetime.now().time()` instead of `None` on invalid input failed `test_parse_time_invalid`, which asserted `None` [11].
So one of two hand-picked mutants died, a 50% kill rate [1] against a 94% coverage number [5], a spread of 44 points on metrics that are not measuring the same thing [3]. Two mutants chosen by the author, applied manually rather than by a mutation runner, is a spot check and not a mutation score [8]. It is still the failure mode you should expect, because the model wrote both the assertions and the fixture files they read from, `sample.csv`, `missing.csv` and `empty.csv` [12]. An input shape the model did not imagine is therefore absent from both sides of the test, and coverage cannot flag it: the missing case is not a line, it is an input. Note also where the two signals landed. The single line coverage reported as unexecuted and the line whose mutant survived are the same line [2].
The author's own reading is that coverage measures lines executed, not behaviours verified, that it is a proxy rather than a guarantee, and that mutation testing is the better check [13][15]. He also rates 20 tests in seconds as a real improvement on zero, as a starting point [14]. Worth knowing before you weight any of this: the piece discloses that it was prepared as part of MonkeyCode's product outreach, and MonkeyCode's free model and free server were what generated and ran the suite [2].
Watch what your acceptance gate actually reads. If generated tests land in CI against a coverage threshold, that threshold is measuring the model's ability to execute lines, which is the thing it is best at. The cheaper tell, before you install a mutation runner: find every `.get()` and every default-value branch in the code under test, then check whether any fixture supplies the absent case. In this instance none did [9].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The author has a small Python library that parses CSV files and extracts course schedules; it reads a CSV, skips header rows, and returns a list of dictionaries, with a function for handling missing values and another for date parsing. It had no tests.
The author used MonkeyCode's free model access and free server, and the article discloses it was prepared as part of MonkeyCode's product outreach.
The prompt asked the model to write pytest tests for the module covering normal cases, missing values, and invalid dates, and to return only the test code.
Run with pytest and coverage.py, the report said 94% coverage, and line 12, the row.get('Course') check, was the only miss.
parse_schedule opens the file, reads it with csv.DictReader, and for each row appends it only if row.get('Course') and row.get('Time') are both truthy, parsing row['Time'] via parse_time before appending.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Reproducible mechanics, unverifiable suite
The module source, prompt, commands and both mutation diffs are shown verbatim, which makes the core demonstration internally coherent and easy to repeat. But everything is one author's self-report: the model is unnamed, only 5 of the 20 tests and no coverage output or fixture files are published, no repository is linked, and only two hand-picked mutants were applied instead of a mutation-testing tool. That supports the narrow finding on this toy module and little beyond it.
Single disclosed anecdote
The only usage fact in the cluster is one author's disclosed trial of MonkeyCode's free tier on a personal module. There are no user numbers, no team or production deployments, no benchmark participation and no evidence that anyone else runs this workflow, so no adoption level can be measured without inventing facts.
Modest claim, slightly overreaching frame
The piece is largely self-deflating: it undercuts its own coverage number and the sponsor's output rather than inflating either. The small positive gap comes from framing — 'the one branch that mattered' and the general lesson about AI-generated suites — being carried by two hand-chosen mutants on a fourteen-line toy module, with no tool-run mutant population, no named model and no baseline human suite for comparison.
Disclosed vendor outreach
The article states outright that it was prepared as part of MonkeyCode's product outreach and that the free model access and free server came from that vendor, and it closes by recommending that free tier to students. The disclosure is prominent and early, which is a mitigant, but the commercial interest is direct and shapes both the tool choice and the closing recommendation.
Clear method, narrow and sponsored base
Confidence in the narrow finding — that this generated suite reported 94% coverage yet missed the absent-'Course'-key behaviour — is fairly high because the code, mutation and reasoning are all shown and internally consistent. Confidence in anything general is low: one sponsored source, one author, an unnamed model, a partially published suite and two hand-applied mutants.
build
Your 90% Cache Hit Ratio Is a Lagging Indicator. Alert on Cold Misses Per Key1 distinct publisher
build
The dangerous cell in your state machine is the one nobody filled in1 distinct publisher
build
Stop timing your GraphQL tests and start counting loader calls1 distinct publisher
build
Your REPL Is Not A Container: Put Free-Variable Checks In CI Before Generated Code Ships1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 20, 2026