Five Ways Test-Driven Development Can Go Wrong

Dave Farley uses testing anti-patterns as signals for improving software design.

DFDave FarleyPonente
Canal
GOTO Conferences
Publicado
7 may 2021
Vídeo
21:34
Lectura
2 min
Original
inglés
Abrir en YouTube
Al desplazarte, el vídeo se reduce a la esquina inferior derecha y sigue reproduciéndose. Los subtítulos siguen tu idioma de lectura.
Idioma de lecturaDisponible en 2 idiomas
Este artículo aún no está en español, así que se muestra el original en inglés.
RESUMEN

En 30 segundos

Dave Farley discusses meaningless assertions, excessive setup, giant tests, over-mocking and tests that inspect private internals. He argues that focused tests and better separation of concerns can turn testing difficulty into design feedback.

  1. 1The liarA passing test without a useful assertion can create false confidence.
  2. 2Excessive setupComplicated setup can reveal difficult dependencies.
  3. 3The giantA large test can obscure which behavior failed.
  4. 4The mockeryMocking everything may leave no real behavior under test.
  5. 5The inspectorAssertions tied to private internals can make tests fragile.

Conclusiones

  1. A passing test without a useful assertion can create false confidence.
  2. Complicated setup can reveal difficult dependencies.
  3. A large test can obscure which behavior failed.
  4. Mocking everything may leave no real behavior under test.
  5. Assertions tied to private internals can make tests fragile.
TEXTO COMPLETO

Lee el texto editado por capítulos

Solo la transcripción
01

Testing as design feedback

Farley introduces the purpose of the feedback loop.

Dave Farley argues that difficulties in test-driven development can signal problems in software design. In this 2021 talk he examines five testing anti-patterns and proposes ways to make feedback more useful.

For Farley, TDD’s value is not just a coverage number: writing tests and code in a short feedback loop can expose coupling, poor separation of concerns and difficult interfaces. These signals still require judgment about the context.

02

Meaningless tests and setup

The first two patterns expose weak assertions and difficult dependencies.

The first anti-pattern, “the liar,” is a test that passes but makes no meaningful assertion. He recalls a coverage target that encouraged tests which executed code without checking useful behavior.

His suggested correction is to remove or improve meaningless tests and observe a new test fail for the intended reason before implementing the behavior. A failing test is useful evidence, though it alone does not guarantee the test is correct.

“Excessive setup” occurs when preparing a test takes a large amount of work. Farley treats this as a prompt to inspect dependencies and separation of concerns, rather than immediately accepting a fragile setup.

He shows a test that starts an entire Jenkins environment to check a URL string. For that particular behavior, a smaller unit-level check may be faster and clearer; broader integration tests can still be appropriate when the interaction itself matters.

03

Large tests and mocks

He discusses unclear intent and overuse of test doubles.

“The giant” is a long test with many assertions and unclear intent. Farley says failures can be hard to diagnose when unrelated behaviors are bundled into one case.

He prefers decomposing such cases into focused tests and suggests one assertion per test as a rule of thumb. Multiple related assertions can also be reasonable when they describe one coherent behavior.

“The mockery” relies on so many mocks or stubs that little or no production behavior is exercised. In his example both the car and engine are mocked, leaving a test of the configured doubles rather than their real implementation.

He recommends reconsidering the design and focusing on the behavior the software must provide. Test doubles can be useful at a boundary, but they should not replace the behavior the test is meant to verify.

04

Encapsulation and behavior

The final pattern concerns tests coupled to internal details.

“The inspector” breaks encapsulation to assert private implementation details. Farley warns that tests coupled to internals may fail after harmless refactoring even when externally observable behavior remains correct.

He shows a method apparently added only for a test and asks whether a better abstraction or dependency boundary would let the test observe behavior without exposing private state. That is a design question, not a prohibition on all test-specific instrumentation.

Across the five patterns, his theme is to use testing friction as feedback: simplify setup, clarify behavior, improve separation and avoid treating coverage as the goal itself.

Más de este canal

3 diapositivas39:12EN
GOTO Conferences· 28 oct 2026Cate Huston: How Rigour Supports AI-Assisted Development VelocityCate Huston · TwillA two-person team’s experience with release gates, automated checks, prioritization and the cost of shipping faster.Liderazgo en ingeniería de IASoftware engineeringAI agents
4 diapositivas22:33EN
GOTO Conferences· 26 oct 2026William Schor: From Unit Tests to Synthetic Canaries at NetflixWilliam Schor · NetflixHow generated workloads and production-like infrastructure help test a distributed key-value service.Software engineering
5 diapositivas34:11EN
GOTO Conferences· 23 oct 2026Anatoliy Bilenko and Alberto Carretero: Making Database Protocols Reliable with Formal Methods and AIAnatoliy Bilenko, Alberto Carretero · CanonicalCanonical’s database engineers connect executable specifications, model-based tests, failure exploration, and reconstructed execution histories—and explain why none of these techniques proves a real system correct on its own.Flujos de desarrollo y pruebasCode review & verificationObservabilidad y fiabilidad+2
28:15EN
GOTO Conferences· 22 oct 2026Steve Poole on Open-Source Security and AI’s Maintenance ChallengeOlimpiu Pop, Steve PooleWhy faster vulnerability discovery increases pressure on maintainers, dependency users and upgrade processes.Software engineeringAI security
5 diapositivas46:36EN
GOTO Conferences· 21 oct 2026Don Syme: Building Agentic Automation Around Human CollaborationDon Syme · GitHubContinuous AI, repository workflows and the guardrails needed for unattended software maintenance.Agent orchestrationSoftware engineeringAgentes de programación
28:23EN
GOTO Conferences· 19 oct 2026Learning Ash: Declarative Elixir Apps, Testing and ExtensibilityChristian Alexander, Rebecca Le, Zach DanielRebecca Le and Zach Daniel explain how their book and the framework evolved together.Software engineering