Good tests catch real bugs in behavior. Change detectors don’t, devs.☝️
By Google for Developers
Key Concepts
- Refactoring: The process of restructuring existing computer code without changing its external behavior.
- Tests: Code written to verify that other code functions as expected.
- Change Detectors: Tests that primarily verify the current implementation rather than the intended behavior, breaking when code changes even if the behavior is correct.
- Brittle Tests: Tests that are easily broken by minor code changes.
- Noisy Tests: Tests that produce false positives or negatives, indicating failures when there are no actual bugs.
- Behavioral Testing: Tests that focus on verifying the observable outcomes or functionality of the code.
The Problem with "Change Detector" Tests
The transcript highlights a common pitfall in software development: writing tests that appear to work but are ultimately useless. This often occurs after refactoring code to make it cleaner. While the refactoring might improve the code's structure, it can lead to a cascade of failing tests. The core issue identified is the nature of these failing tests – they are not truly verifying behavior but rather acting as "change detectors."
What are Change Detector Tests?
Change detector tests are characterized by their inability to distinguish between correct and incorrect code. They essentially "replay the code," meaning they check if the output matches what the code currently produces, regardless of whether that output is the intended or correct behavior. The transcript uses an analogy of a "glorified check sum," implying that even broken code could pass these tests.
Specific Example of a Useless Test: The transcript provides a hypothetical example:
// This test is clearly not useful since it just replays the code.
// It's a glorified check sum. Even broken code would pass.
While the exact code isn't shown, the description emphasizes that the test's logic is tied to the current implementation's output, not its functional correctness.
Realistic Examples and Their Pitfalls
The transcript acknowledges that while the initial example might seem absurd, many real-world tests exhibit similar flaws. A more realistic, though still problematic, test scenario is described:
- Temptation: Developers are tempted to write tests that require "little thought" and "run quickly."
- The Illusion of Testing: These tests give the impression of verifying something, but "no behavior is actually being tested."
- The Core Misconception: The test asserts "this is what the code currently does, not this is what the code is supposed to do."
This distinction is crucial: good tests validate the intended functionality (what the code should do), while change detectors validate the current implementation (what the code currently does).
Consequences of Change Detector Tests
The transcript outlines several negative impacts of relying on change detector tests:
- Brittleness: They break easily with minor code modifications, even if the underlying behavior remains correct.
- Noise: They generate false alarms, leading developers to waste time investigating non-existent bugs.
- Slowdown: They hinder development velocity by requiring developers to fix or delete them, and by providing misleading feedback.
- Failure to Catch Bugs: Crucially, they do not identify actual bugs in the code's behavior.
The Argument for Deletion or Rewriting
The central argument presented is a strong call to action: "Delete them or rewrite them, but please don't keep them." The transcript advocates for tests that "catch real bugs in behavior" rather than those that merely detect changes in the code.
Logical Connections and Overall Argument
The transcript builds its argument by:
- Identifying a common problem: Failing tests after refactoring.
- Diagnosing the root cause: The nature of the tests themselves – they are "change detectors."
- Explaining the mechanism: How these tests focus on current implementation rather than intended behavior.
- Illustrating with examples: From an absurd hypothetical to more realistic scenarios.
- Detailing the negative consequences: Brittleness, noise, and development slowdown.
- Proposing a solution: Deleting or rewriting these ineffective tests.
The logical flow moves from observing a symptom (failing tests) to diagnosing the underlying disease (change detector tests) and prescribing a cure (deletion or rewriting).
Conclusion/Synthesis
The main takeaway is that tests should be designed to verify the intended behavior of the code, not just its current implementation. "Change detector" tests, which break when code is modified even if the behavior is correct, are detrimental to development. They are brittle, noisy, and slow down the development process without catching actual bugs. Developers are urged to identify and eliminate these ineffective tests, replacing them with tests that provide meaningful feedback on the code's functionality.
Chat with this Video
AI-PoweredHi! I can answer questions about this video "Good tests catch real bugs in behavior. Change detectors don’t, devs.☝️". What would you like to know?