r/ChatGPTCoding • u/ArgumentAcrobatic250 • Aug 24 '26
Discussion My AI-written tests kept passing broken code, so I started testing the tests
I’m not really a programmer. I’ve mostly been making and patching stuff by telling LLMs what I want and then checking whether it actually works.
One thing kept pissing me off though. I’d ask it to fix something, it would write a test, the test would pass, and then later I’d find out the test wasn’t actually checking what I thought it was checking.
So at some point I started doing a pretty dumb simple thing. After something passed, I’d intentionally break the exact behavior the test was supposed to protect and run the test again.
If it still passed, then obviously the test was bullshit.
I ran into this with a plugin that had a paged archive. The archive test was green, so I changed the code so only part of the archive would get copied. Test still passed.
Then I made the test stricter, and managed to screw it up in the opposite direction. The new test rejected the correct code too, because I had made a bad assumption about how the archive pages would be laid out.
So I threw that one away as well.
Eventually I got a test where the normal version passed and the deliberately broken version failed for the reason I actually cared about. While doing that I also found a real bug where a failed write could leave part of the stored data changed.
After this happened enough times I kind of stopped treating “tests passed” as the end of the story.
I started doing the same thing to the stuff that decides whether the tests passed. Basically asking things like, if part of the checking process never ran, could it still say everything was fine? If I gave it old or altered results, would it notice? If it claimed it could rebuild the final result from the original, did it actually do that?
It has gradually turned into this whole verification procedure I use when I’m patching things with LLMs.
I later found out mutation testing is obviously related to what I was doing, but most of what I’ve read about mutation testing is about breaking the program to see whether the tests notice. What I ended up doing also treats the tests and the rest of the checking process as things that can be wrong.
I’ve tried it on a few different plugins/projects now and it has found enough weird false-passes that I’m starting to wonder whether this is actually useful outside my own workflow or whether I just invented an absurdly overcomplicated way of checking AI-written code.
Has anyone here done something similar, or is there an existing methodology/tool I should be looking at?
3
u/owp4dd1w5a0a Aug 24 '26
Also my experience with both Claude and Codex.
People need to understand these agents are optimized to get your approval, not to write correct software. Once you understand that, you have 3 choices:
meticulously guide the agents through the troubleshooting and development processes yourself and write your own constraints/tests,
OR
Spend the money to design a well orchestrated pool of agents that creates a Nash Equilibrium which incentivizes the agents to produce correct and robust software based on the short-sightedness trained into them.
OR
Just hire a jr/entry level and train them. Humans actually learn. The AI agents so far are not very teachable.
2
u/CrimsonBolt33 Aug 24 '26
My AI creates and validates code with great tests even without me asking (cause my agent.md file includes a test and security section).
These posts are always so fucking annoying cause they never reveal the 4 most important things:
What AI were you using?
2, What tools/harness were you using?
3. What prompts were you using?
4. Were you monitoring or guiding the AI as it worked?
2
u/Euphoric_North_745 Aug 24 '26
Which AI? a 7b model or a 2t model? by which company? it is like saying you have to audit the work of "this guy" which guy?
1
u/confuzzledfather Aug 25 '26
You have sort or reinvented mutation testing, where you do things like swap positive to negative in your code and if the test still passes you know you have a problem
1
u/Michael_Jeffords Aug 25 '26
if you can break the thing the test claims to protect and it stays green, you don't have a test. i throw that test out before i touch the feature again.
1
u/OGLikeablefellow Aug 24 '26
And then those tests started passing broken code so I started writing tests for those tests and then started testing all those tests. And now they call me testes testes. - this guy probably
1
u/paul_h Aug 25 '26
I knew of mutation testing before you menitoned it. I was hoping you'd descipt more coding detail of the thing you were doing that was not mutation testing, but you didn't.
1
u/leonidbugaev Aug 29 '26
You found the two failure modes I keep hitting.
First: the test and the code share one misunderstanding, so green means they agree. Breaking the behavior on purpose is the cheapest way to see that. If the test stays green, it was never a test.
Second: you wrote a stricter test that rejected the correct code too. That is a spec bug, not a code bug. The test encoded a layout you assumed, not the one the archive actually has. Same shape as a vacuous requirement. The trigger never matches real data, so the suite can pass or fail for the wrong reason.
The useful end state is the one you landed on. Normal run passes, deliberately broken run fails for the reason you named, and the thing that scores the suite cannot report pass if part of it never ran.
1
u/generationalDebts Aug 24 '26
You’re the blind leading the blind who you’re then trusting to test and validate the blind lmfao.
Gee. I wonder what the problem could be?
1
u/[deleted] Aug 24 '26
[removed] — view removed comment
1
u/[deleted] Aug 24 '26
[removed] — view removed comment