conv.

All stories
TechQuiet 9d · day 11

The Kluever Maneuver: Writing Tests That Fail Before Fixing Bugs

Developer Jordi Gómez Hernández names a technique for writing regression tests that demonstrate bugs before fixes are applied.

What to know

  • The Kluever Maneuver is a code-review technique where developers write tests demonstrating buggy behavior before applying fixes, ensuring the test actually fails on broken code and passes after the fix.
  • The approach is already standard practice in several major projects (Rust, Cargo, LLVM) as a two-commit pattern: one commit with a failing test, one with the fix that makes it pass.
  • Developers disagree on implementation details: some prefer explicit 'terrible tests' of incorrect behavior; others advocate 'expected to fail' annotations to encode intent more explicitly.
  • The technique catches a gap in traditional fix-and-test workflows where a proposed bugfix might not actually address the problem, but the added test passes anyway.

The dispute Whether to write tests that pass with buggy behavior (Kluever approach) or write correct tests marked as 'expected to fail' (xfail approach), with advocates on both sides citing code clarity and maintainability. · positions read across 36 posts and comments

many voices

Write tests that assert buggy behavior before fixes, catching unrelated fixes.

  • “It cuts a commit down to the esentials to better see what changed and it is a much better illustration of what a PR does than the description.”

    epage · Lobsters comment ↗
many voices

Use 'expected to fail' annotations instead, preserving intent without misleading tests in code.

  • “'Known failing' would let you do it in a more natural way: write the test for the correct behavior, and mark it as 'expected to fail'.”

    nedbat · Lobsters comment ↗
some voices

The choice depends on clarity: use whichever method better communicates the bug to reviewers.

  • “For me, a key point of this is to make the change of behavior clear, complementing the PR description. If an 'expect fail' doesn't clearly communicate what operation failed and how, then I'd rather switch the code to assert that condition.”

    epage · Lobsters comment ↗

Jordi Gómez Hernández Developer and writerKurt Kluever Developer (originator of technique)

How it unfolded 4 developments, newest first · click a bar or a number to jump postscomments

Peak 11 pieces in 3h at Oct 31, 10 AM; 39 pieces over 11 days (3 posts · 36 comments) Oct 31, 10 AM — 11 pieces · 2 posts · 9 comments — Lobsters 10, Hacker News 1Oct 31, 1 PM — 4 pieces · 4 comments — Lobsters 4Oct 31, 4 PM — 2 pieces · 2 comments — Lobsters 2Oct 31, 7 PM — 1 piece · 1 comment — Lobsters 1Oct 31, 10 PM — 2 pieces · 2 comments — Lobsters 2Nov 1, 1 AM — 3 pieces · 3 comments — Lobsters 3Nov 1, 3 AM — quietNov 1, 6 AM — 4 pieces · 4 comments — Lobsters 4Nov 1, 9 AM — 3 pieces · 1 post · 2 comments — Lobsters 2, Hacker News 1Nov 1, 12 PM — 2 pieces · 2 comments — Lobsters 2Nov 1, 3 PM — 2 pieces · 2 comments — Lobsters 2Nov 1, 6 PM — 1 piece · 1 comment — Lobsters 1Nov 1, 9 PM — quietNov 2, 12 AM — quietNov 2, 3 AM — quietNov 2, 6 AM — 1 piece · 1 comment — Lobsters 1Nov 2, 9 AM — quietNov 2, 12 PM — quietNov 2, 3 PM — quietNov 2, 6 PM — quietNov 2, 9 PM — 3 pieces · 3 comments — Lobsters 3Nov 3, 12 AM — quietNov 3, 3 AM — quietNov 3, 6 AM — quietNov 3, 9 AM — quietNov 3, 12 PM — quietNov 3, 3 PM — quietNov 3, 6 PM — quietNov 3, 9 PM — quietNov 4, 12 AM — quietNov 4, 3 AM — quietNov 4, 6 AM — quietNov 4, 9 AM — quietNov 4, 12 PM — quietNov 4, 3 PM — quietNov 4, 6 PM — quietNov 4, 9 PM — quietNov 5, 12 AM — quietNov 5, 3 AM — quietNov 5, 6 AM — quietNov 5, 9 AM — quietNov 5, 12 PM — quietNov 5, 3 PM — quietNov 5, 6 PM — quietNov 5, 9 PM — quietNov 6, 12 AM — quietNov 6, 3 AM — quietNov 6, 6 AM — quietNov 6, 9 AM — quietNov 6, 12 PM — quietNov 6, 3 PM — quietNov 6, 6 PM — quietNov 6, 9 PM — quietNov 7, 12 AM — quietNov 7, 3 AM — quietNov 7, 6 AM — quietNov 7, 9 AM — quietNov 7, 12 PM — quietNov 7, 3 PM — quietNov 7, 6 PM — quietNov 7, 9 PM — quietNov 8, 12 AM — quietNov 8, 3 AM — quietNov 8, 6 AM — quietNov 8, 9 AM — quietNov 8, 12 PM — quietNov 8, 3 PM — quietNov 8, 6 PM — quietNov 8, 9 PM — quietNov 9, 12 AM — quietNov 9, 3 AM — quietNov 9, 6 AM — quietNov 9, 9 AM — quietNov 9, 12 PM — quietNov 9, 3 PM — quietNov 9, 6 PM — quietNov 9, 9 PM — quietYesterday, 12 AM — quietYesterday, 3 AM — quietYesterday, 6 AM — quietYesterday, 9 AM — quietYesterday, 12 PM — quietYesterday, 3 PM — quietYesterday, 6 PM — quietYesterday, 9 PM — quietToday, 12 AM — quietToday, 3 AM — quietToday, 6 AM — quietToday, 9 AM — quietToday, 12 PM — quietToday, 3 PM — quietToday, 6 PM — quiet 1–4
Nov 1Nov 2Nov 3Nov 4Nov 5Nov 6Nov 7Nov 8Nov 9yesterdaynow · 7:50 PM ET
  1. 4

    Developers debate tradeoffs between test approaches

    Discussion emerges over whether 'expected to fail' annotations or explicit tests of buggy behavior better serve code review clarity and maintainability, with no consensus reached.

    “For me, a key point of this is to make the change of behavior clear, complementing the PR description. If an 'expect fail' doesn't clearly communicate what operation failed and how, then I'd rather switch the code to assert that condition.”
    — epage
    • "Known failing" would let you do it in a more natural way: write the test for the correct behavior, and mark it as "expected to fail". Then you can commit the fix to the code, with the change to remove the fail expectation. The Kluever Maneuver seems odd to me: write the test confirming the wrong behavior. I'd rather have the first commit confirm…

      nedbattesting11d ago20▲view on Lobsters ↗
    2 more of the top 3 · 30 posts in this stretch
    • I don't think I like committing passing but known-wrong tests to the codebase, even if immediately patched. But I could see the argument if you mark the test `XFAIL` and then fix the bug in the commit that removes the `XFAIL` mark.

      jackdktesting10d ago20▲view on Lobsters ↗
    • https://lobste.rs/c/72mqyb proposes using "expect fail" for such tests at first, which encodes the expectation in a way that is verifiable, and easy to flip (and to verify that change to the test) when the fix arrives.

      pgeorgitesting11d ago9▲view on Lobsters ↗
    all of them →
  2. 3

    Rust contributors confirm widespread adoption of two-commit bug-fix pattern

    Jana notes the technique is standard practice in Rust language contributions, where bug-fix pull requests split into two commits: one demonstrating the bug, one fixing it.

    “I love this. It's one of the things I very often ask new contributors to rust-lang/rust to do when reviewing, and it's become kind of a standard. Any bug fix pr is two commits, and imo that's extremely important.”
    — jana
    • I love this. It's one of the things I very often ask new contributors to rust-lang/rust to do when reviewing, and it's become kind of a standard. Any bug fix pr is two commits, and imo that's extremely important.

      janatesting11d ago5▲view on Lobsters ↗
    2 more of the top 3 · 3 posts in this stretch
    • I'm familiar with this from contributing to LLVM.

      majahatesting11d ago2▲view on Lobsters ↗
    • I usually do this by adding a test for the fixed bug and a test that demonstrates the bug in action, but this is an interesting modification of the idea.

      icefoxtesting11d ago1▲view on Lobsters ↗
    all of them →
  3. 2

    Developers cite prior art and alternative methodologies

    Comments note that similar techniques have been used in projects like Aegis, Cargo, and the Rust compiler, with some preferring 'expected to fail' annotations over writing tests that pass with incorrect behavior.

    “So you submit a change, which comes with a test (for new features, the test would fail because there's no feature to exercise), and aegis would only merge the change if the test-on-its-own failed and passes with the change.”
    — pgeorgi
    • A couple, yeah. TDD would have you write a test asserting the *correct* behavior that initially fails, while this methodology has you write a test asserting the *incorrect* that initially passes, but must be fixed. Also, more broadly, TDD is a practice that asserts that any code change, from new features to bug fixes, should be preceded by the…

      jdpagetesting11d ago14▲view on Lobsters ↗
    2 more of the top 3 · 3 posts in this stretch
    • https://aegis.sourceforge.net/ went a step further and expected only the correct test, but had some rules on how it can backport it separate from the fix. So you submit a change, which comes with a test (for new features, the test would fail because there's no feature to exercise), and aegis would only merge the change if the test-on-its-own…

      pgeorgitesting11d ago9▲view on Lobsters ↗
    • Is there a difference between this and TDD?

      ryan-duvetesting11d ago1▲view on Lobsters ↗
    all of them →
  4. 1

    Jordi Gómez Hernández publishes article on regression-test technique

    Article posted to Lobsters and Hacker News describing a method for writing tests that demonstrate bugs before fixes are applied, attributed to Kurt Kluever.

    “But what if the test accidentally already passed before the alleged bugfix and the alleged bugfix didn't actually work? In that case the added test gives false confidence that the bugfix worked.”
    — Jordi Gómez Hernández, Author · source

What people are saying 16 voices from 1 site · best of 36 · verbatim