Write Antifragile & Domain-Driven
Tests with
• THOMAS PIERRAIN
(@TPIERRAIN)
ACCEPTANCE TESTS
(COARSE-GRAINED “UNIT” TESTS)
UNIT TESTS
(FINE-GRAINED)
CONTRACT TESTS
INTEGRATION TESTS
QA
SMOKE TESTS
EXPLORATORY TESTS
END-TO-END TESTS
OUTSIDE-IN
DIAMOND
TDD
Disclaimers
There is no silver bullet Your testing strategy & techniques must always be
chosen accordingly to your context (both human & technical)
As long as you understand your trade-offs there is no reason not to
explore new paths…
Thanks to Kent Beck, Martin Fowler, Michael Feathers, Nat Pryce & Steve Freeman for their great source of
inspiration over the years #shouldersOfGiants
Preamble
BFF API
Booking
API
E-commerce
CRS API
Central
Reservation
U
d
PSP
API
Payment
U
d
• THOMAS PIERRAIN
(@TPIERRAIN)
Metasearch
API
Distribution
U
d
Resorts
Referential
CMS
API
Property
Management
System (PMS)
Stay
U
d
U
d
Rates &
Cancellation rules
API
Revenue Mgmt
U
d
U
d
Hospitality
U
d
Accounts
API
Loyalty
API
Marketing
DDD
LOVES…
(Contextualized)
Services
E-commerce
Central
Reservation
U
d
Payment
U
d
• THOMAS PIERRAIN
(@TPIERRAIN)
Distribution
U
d
Resorts
Referential
Stay
U
d
U
d
Revenue Mgmt
U
d
U
d
U
d
Marketing
Accounts
API
Loyalty
API
DDD
LOVES…
(Contextualized)
Services
BFF API
Booking
API
CMS
API
PSP
API
CRS API
Rates &
Cancellation rules
API
Metasearch
API
Property
Management
System (PMS)
Hospitality
• THOMAS PIERRAIN
(@TPIERRAIN)
DDD (& TDD)
ALSO
LOVES… DOMAIN
HTTP
HTTP
API
INFRASTRUCTURE
OUR WEB API
Ports &
Adapters
• THOMAS PIERRAIN
(@TPIERRAIN)
DDD (& TDD)
ALSO
LOVE… DOMAIN
HTTP INFRASTRUCTURE
OUR WEB API
Ports &
Adapters
Easy to test
Protect Domain code from
Infra fads
Quick feedback
(carpaccio-style slicing)
Allow late
architectural decisions
Composable:
modular-monolith ready HTTP
API
• THOMAS PIERRAIN
(@TPIERRAIN)
DDD (& TDD)
ALSO
LOVE… DOMAIN
INFRASTRUCTURE
Ports &
Adapters
• THOMAS PIERRAIN
(@TPIERRAIN)
DDD (& TDD)
ALSO
LOVE… DOMAIN
HTTP INFRASTRUCTURE
OUR WEB API
Ports &
Adapters
HTTP
API
Let’s talk about tests!
• THOMAS PIERRAIN
(@TPIERRAIN)
Different
Types
A WORLD
OF TESTS
ET Exploratory Tests (E2E)
IT Integration Tests (Contract)
AT
(coarse-grained unit)
Acceptance Tests
UT (fine-grained) Unit Tests
Why do I do TDD?
Made me…
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
More relaxed
More efficient
More relevant
TDD Workflows
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
AT
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
AT
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT AT
AT
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT AT
AT
AT
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT AT
AT
AT
AT
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT AT
AT
AT
AT
AT
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT AT
AT
AT
AT
AT
AT
Outside-in
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
AT
AT
AT
AT
AT
AT
AT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
UT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
UT
UT
API
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
UT
UT
API UT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
UT
UT
API UT
UT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
API
UT
UT
UT
UT
UT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
API
UT
UT
UT
UT
UT
UT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
API
UT
UT
UT
UT
UT
UT
UT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
API
UT
UT
UT
UT
UT
UT
UT
AT
Inside-out
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
API
UT
UT
UT
UT
UT
UT
UT
AT
AT
Workflows
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
Outside-in Inside-out
A
P
I
…
…
A
P
I
Common pitfalls & mitigations
• THOMAS PIERRAIN
(@TPIERRAIN)
Beware of…
TEST
DRIVEN
DEVELOP
MENT
1. Fragile tests
2. Blind spots
3. Complex setups
TEST
DRIVEN
DEVELOP
MENT
1.
Beware of…
Fragile tests
uses
API
uses
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
AT
UT
UT
UT
UT
UT
UT
AT
uses
API
1.
Beware of…
Fragile tests
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT UT
UT
AT
UT
UT
UT
UT
AT
uses
API
Now we want to change
our implementation here
1.
Beware of…
Fragile tests
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT UT
UT
AT
UT
UT
UT
UT
AT
uses
API
1.
Beware of…
Fragile tests
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT UT
UT
AT
UT
UT
UT
UT
AT
😕
😕 😕
😕
😕
uses
API
1.
Beware of…
Fragile tests
😕
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT UT
UT
AT
UT
UT
UT
UT
AT
😕
😕 😕
😕
😕
uses
API
Fragile tests
➔ Less refactoring
😕
• THOMAS PIERRAIN
(@TPIERRAIN)
UT
UT
AT
UT
UT
UT
UT
AT
😕
😕 😕
😕
😕
uses
API
TEST
DRIVEN
DEVELOP
MENT
Fragile tests
MITIGATIONS
• Do not test “implementations”
• Focus on external behaviours
instead (with Outside-in TDD)
• Favor (coarse-grained unit)
Acceptance tests over fine-
grained unit tests
A
P
…
…
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT Disclaimer
Test Coverage will be a visual help to
identify blind spots in our code here
It doesn’t mean that test coverage is a
must
2.
Beware of…
Blind Spots
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
DOMAIN
HTTP
HTTP
API
INFRASTRUCTURE
OUR WEB API
2.
Beware of…
Blind Spots
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
DOMAIN
Test the domain code with
{ acceptance | unit tests }
2.
Beware of…
Blind Spots
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
DOMAIN
HTTP
API
Test the domain code with
{ acceptance | unit tests }
Test the infra code (i.e. Adapters) with
contract (integration) tests
2.
Beware of…
Blind Spots
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
2.
Beware of…
Blind Spots
IT
IT
IT
IT
HTTP
API

CONTRACT TESTS
DOMAIN
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
100% covered
by Acceptance
Tests
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
2.
Beware of…
Blind Spots
IT
IT
IT
IT
HTTP
API

CONTRACT TESTS
DOMAIN
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
100% covered
by Acceptance
Tests
As DEV we
to write Domain-
Driven tests
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
2.
Beware of…
Blind Spots
IT
IT
IT
IT
HTTP
API

CONTRACT TESTS
DOMAIN
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
100% covered
by Acceptance
Tests
As DEV we
to write Domain-
Driven tests
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
2.
Beware of…
Blind Spots
As DEV we don’t write
enough integration tests
Because they are slow to
run & boring
➔ BUGS
IT
IT
IT
IT
HTTP
API

CONTRACT TESTS
DOMAIN
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
100% covered
by Acceptance
Tests
As DEV we
to write Domain-
Driven tests
As DEV we don’t write
enough integration tests
Because they are slow to
run & boring
➔ BUGS
IT
IT
IT
IT
HTTP
API

CONTRACT TESTS
DOMAIN
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
AT
100% covered
by Acceptance
Tests
As DEV we
to write Domain-
Driven tests
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
Blind Spots
MITIGATIONS
• Detect bugs in Adapters
via our beloved Acceptance
tests
• Include the Adapters code
and stub only the I/Os
BUGS
• THOMAS PIERRAIN
(@TPIERRAIN)
TEST
DRIVEN
DEVELOP
MENT
3.
Beware of…
Complex
setups
• THOMAS PIERRAIN
(@TPIERRAIN)
Test Suite for Rooms Availability
TEST
DRIVEN
DEVELOP
MENT
3.
Beware of…
Complex
setups
740 lines of Init()
• THOMAS PIERRAIN
(@TPIERRAIN)
Test Suite for Rooms Availability
TEST
DRIVEN
DEVELOP
MENT
3.
Beware of…
Complex
setups
740 lines of Init()
• THOMAS PIERRAIN
(@TPIERRAIN)
Test Suite for Rooms Availability
TEST
DRIVEN
DEVELOP
MENT
3.
Beware of…
Complex
setups
740 lines of Init()
• THOMAS PIERRAIN
(@TPIERRAIN)
Test Suite for Rooms Availability
TEST
DRIVEN
DEVELOP
MENT
3.
Beware of…
Complex
setups
Tests using initialized fields
➔ side effects nightmare
• THOMAS PIERRAIN
(@TPIERRAIN)
MITIGATIONS
• Avoid cognitive overload as much as
possible
The power of sameness
• Favor local variables over test suite
members
Everything should be created from the test
• Use Domain-Driven Builders to shorten
and explicit the Arrange section of your
tests
• Treat your test code as production code!
➔ merciless refactoring
TEST
DRIVEN
DEVELOP
MENT
3.
Beware of…
Complex
setups
• THOMAS PIERRAIN
(@TPIERRAIN)
Beware of…
TEST
DRIVEN
DEVELOP
MENT
1. Fragile tests
2. Blind spots
3. Complex setups
• THOMAS PIERRAIN
(@TPIERRAIN)
1. Fragile tests
2. Blind spots
3. Complex setups
Mitigations
TEST
DRIVEN
DEVELOP
MENT
• THOMAS PIERRAIN
(@TPIERRAIN)
1. Fragile tests
2. Blind spots
3. Complex setups
Mitigations
TEST
DRIVEN
DEVELOP
MENT
• THOMAS PIERRAIN
(@TPIERRAIN)
1. Fragile tests
2. Blind spots
3. Complex setups
Mitigations
TEST
DRIVEN
DEVELOP
MENT
Outside-in Diamond TDD
Outside-in Diamond TDD
Outside-in Diamond TDD
• THOMAS PIERRAIN
(@TPIERRAIN)
Outside-in
but…
TEST
DRIVEN
DEVELOP
MENT
Double loop?
• THOMAS PIERRAIN
(@TPIERRAIN)
Outside-in
but…
TEST
DRIVEN
DEVELOP
MENT
Double loop
• THOMAS PIERRAIN
(@TPIERRAIN)
Outside-in
but…
TEST
DRIVEN
DEVELOP
MENT
Double loop
One and a half loop
( )
OUTSIDE-IN
DIAMOND
OUTSIDE-IN
DIAMOND
OUTSIDE-IN
DIAMOND
Read it as a sentence divided into 2 parts
+
OUTSIDE-IN
DIAMOND
Fuzzers help us
- to randomly detect hard-coded values
or unsupported cases
OUTSIDE-IN
DIAMOND
Fuzzers help us
- to randomly detect hard-coded values
or unsupported case
- to shorten our test setup
OUTSIDE-IN
DIAMOND
Builders allow Behavioral
& Domain-Driven intentions
(no tech details here)
OUTSIDE-IN
DIAMOND
Builders allow Behavioral
& Domain-Driven intentions
(no tech details here)
OUTSIDE-IN
DIAMOND
Builders allow Behavioral
& Domain-Driven intentions
(no tech details here)
OUTSIDE-IN
DIAMOND
Builders allow Behavioral
& Domain-Driven intentions
(no tech details here)
OUTSIDE-IN
DIAMOND
Builders allow Behavioral
& Domain-Driven intentions
(no tech details here)
OUTSIDE-IN
DIAMOND
Builders allow Behavioral
& Domain-Driven intentions
(no tech details here)
Very important!
OUTSIDE-IN
DIAMOND
We test from the left-side Adapter
(here a web controller)
Injecting the result of our builder
OUTSIDE-IN
DIAMOND
We define the end-user request
No I/O here, but we test
the whole { black-box / component / API }
OUTSIDE-IN
DIAMOND
Helper method to sum-up in “one line”
our assert intention
OUTSIDE-IN
DIAMOND
“One line” to hide our
technical assertions
towards DTOs etc.
OUTSIDE-IN
DIAMOND
“One line” to hide our
technical assertions
towards DTOs etc.
“One line” to reuse the same
check intention, but with
various adapters
OUTSIDE-IN
DIAMOND
OUTSIDE-IN
DIAMOND
OUTSIDE-IN
DIAMOND
OUTSIDE-IN
DIAMOND
OUTSIDE-IN
DIAMOND
OUTSIDE-IN
DIAMOND
ARRANGE
ACT
ASSERT
OUTSIDE-IN
DIAMOND
ARRANGE
ACT
ASSERT
Fuzzers to shorten & speed setup
Builders to shorten and
“domain-driven” our test setup
OUTSIDE-IN
DIAMOND
Domain-Driven!
Live code
Wrap up
Outside-in Diamond TDD
• Elaborated from & for the people
• Write fast & Antifragile tests
( refactoring )
• DDD but covers more blind spots
on the tech side
Outside-in Diamond TDD
• Elaborated from & for the people
• Write fast & Antifragile tests
( refactoring )
• DDD but covers more blind spots
on the tech side
Any Questions?
BINARY IS FOR MACHINE
CODE IS FOR PEOPLE
WE CARE PEOPLE
Special thanks to: Bruno BOUCARD, Cyrille DUPUYDAUBY & Rui CARVALHO for their kind reviews & feedbacks

Write Antifragile & Domain-Driven tests with ”Outside-in diamond” ◆ TDD