Speaker: Jérémy SORANT – 15+ years as dev, co-organizer for Software Crafters Lyon – Currently working at SHODO Lyon
This talk dives into the most common frustrations developers face with tests—fragility, slowness, and maintainability—and presents architecture and mindset shifts that can transform testing from a blocker into a valuable tool.
1. Fragility: The Fear of Breaking Things
- Common situation: A small change breaks dozens of tests → discourages improvements or refactoring.
- Leads to “workarounds” instead of proper fixes → bloated, sad codebases.
- Core issue: Tests often validate implementation details, not product behavior.
Solution: Shift to Behavior-Driven Testing
- Traditional unit test = testing Class A / Function B with mocks everywhere.
- This approach couples tests to structure → highly fragile.
- Instead, use sociable tests: test system behaviors rather than isolated code.
- Follow Given/When/Then (GWT) or similar formats:
- Don’t care how it works, only that it works.
- Implementation can evolve without breaking tests.
Pro Tip: After a TDD session, review your tests
- Not all are worth keeping.
- Remove ones that are too tightly bound to implementation or outdated use cases.
2. Slowness: When Tests Are Too Heavy
- Testing becomes painful when:
- Needs a database or full system running (E2E style).
- Tests are slow, flaky, or hard to set up.
- Outcome: People write fewer tests, or skip them altogether.
Solution: Decouple & Invert
- Identify hard-to-test code and extract it from the core logic.
- Use dependency inversion: separate interfaces from concrete implementations.
- Example: abstract DB access behind an interface → easily mockable.
- Embrace Clean Architecture or Hexagonal Architecture:
- Protect the core product logic from tech-specific concerns.
- Start testing from acceptance-level based on product rules.
3. Maintainability: Keep Tests Clean & Clear
- Issues:
- Tests are hard to understand.
- Errors are cryptic.
- Test code is duplicated with minor variations.
- Results in wasted time during debugging or onboarding.
Best Practices for Maintainable Tests:
- Use Fixtures: Define examples based on real product scenarios.
- Reveal intention:
- Use product language in test names.
- Explicitly tie each test to a single product rule.
- Structure clearly (GWT / AAA):
- One rule per test → better readability.
- Avoid implementation leaks: test outcomes, not internals.
- Write custom assertions and use testing frameworks that give clear, actionable errors
Conclusion
- Test behaviors, not implementations: stable tests lead to confident devs.
- Architecture matters: a testable codebase is a maintainable codebase.
- Tests are as important as production code.
- TDD can transform your development mindset—but it requires coaching and practice.
- Keep your test strategy product-centric, adaptable, and clean.