0:00
/
0:00
Preview

Unit Tests - Live Q&A (Part 1) - Sociable vs Solitary

Watch my Live Q&A Session (2nd April) replay where I explain the difference between Sociable and Solitary Unit Tests, and why I prefer Sociable Unit Tests by default

During our Live Q&A Session, we addressed the question posted by Leandro:

What are your learnings, insights, and reflections from your experience and learning process applying TDD? I mean, like the one you mentioned in the first Q&A about sociable and solitary unit testing—particularly your reflection on initially thinking that solitary unit testing should be the way to go, but then discovering that it makes refactoring very difficult, and learning that sociable unit testing is the better approach.

Test Coupling: Behavior vs Structure

Kent Beck wrote the following:

“Tests should be coupled to the behavior of code and decoupled from the structure of code.” - Kent Beck

Tests should be coupled to Behavior

“Tests should be coupled to the behavior of code…” - Kent Beck

Requirements specify behavior, which is encoded in tests; tests are executable specifications of behavior.

Hence it is expected that when requirements change, we need to update tests to reflect the changed behavior. This naturally causes the tests to fail because the tests are expressing the changed behavior whereas the code is acting in accordance with the old behavior.

Tests should NOT be coupled to Structure

“Tests should be… decoupled from the structure of code.” - Kent Beck

To implement a certain behavior, we could structure our code in a multiple of ways. We could use one class, or maybe one class split into multiple classes. We could use if-else statements or we could use the Strategy Pattern, etc. Whichever structure we choose, it must satisfy the behavior specified.

Over time, we’re also free to make structural changes but without changing the behavior, aka refactoring (Martin Fowler):

Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

Refactoring (verb): to restructure software by applying a series of refactorings without changing its observable behavior.

Since tests should not be coupled to structure (as already said by Kent Beck) it means that tests should NOT break in response to structural changes.

This is where many developers make a mistake - they write Unit Tests which are coupled to structure!

What’s the solution? What kind of Unit Tests are decoupled from structure?

This post is for paid subscribers