SlideShare a Scribd company logo
TDD done “right” -
tests immutable to
refactor
Grzesiek Miejski
Quick survey
Little about me
● Coding microservices for ~4 years
● Different languages and technologies:
○ now: Go, python
○ previously: Kotlin, Java
○ MongoDB, SQL, ElasticSearch, Cassandra, Kafka, RabbitMQ, blabla
Are there not enough TDD materials
already?
My previous problems with tests
● changing business logic made me change tests a lot
● refactoring made me change tests
● applied “real” TDD only to the simplest code, with structure predicted upfront
Is it worth trying then?
Quick survey 2
But in what context?
When my advices are applicable for me?
● everywhere where you want you software to last and be developed
● when building microservices, as this is what I do right now
● but would try love to try those practices in monolith written from start!
Plan for presentation
1. About architecture
2. Unit and Facade
3. Unit and Integration tests
4. Unit tests in BDD style done right
5. Project immutable to refactor - example
6. DO’s and DONT’s
7. TDD goes live!
Example project - movie renting site
Simplified requirements:
● view available movies
● rent movie by user
● return movie by user
● prolong rented movie
● get movie recommendations
● ...
(Normally should be some user stories or whatever)
Example project - movie renting site
Example user stories:
● As a user I cannot rent more than 2 movies at same time
● As a user I cannot rent movies for which I’m too young
● As a user I cannot rent more movies if I have a fee to pay for keeping to long
● As a user ...
Let’s start coding!!!!!!
What is architecture?
“Architecture is a set of rectangles and arrows, where:
● arrows are directed and
● there are no cycles
Rectangles are on it’s own build from rectangles and
arrows.“
What is architecture?
“Architecture is not discovered with unit testing,
it must be done upfront”
What is a unit?
Units:
● units ~~ top-level rectangles
● communicate with other units
○ synchronously or asynchronously
● fulfills specific business cases (single responsibility)
○ made public to the world via a well designed API (called Facade later)
● can have completely different architecture (CQRS, actors, event sourcing...)
Renting site architecture
Users
Add
Get
Movie
Added
Add
Get
Movies
ListGenre
Rent
Rent
Return
Prolonge
Get
Rented
Movie
Rented
Movie
Prolonged
Movie
Returned
Fees
Get
Fees
Pay
Movie
Rented
Movie
Prolonged
Movie
Returned
Recommendations
Get
Search
Search
Add
Movie
Added
Description
Event
produced
Event
consumed
synchronous call
asynchronous call
Unit
Units API - Facade
● use Facade to export available actions
Example Facade
Terminology - Tests kinds
● Unit ~~ module ~~ bounded context
○ module encapsulates it’s data and logic (use DTO to communicate)
○ modules are sliced vertically (all layers)
● Unit tests - checks your business logic (with no external dependencies)
● Integration tests - check your connection with external stuff (DB, HTTP api,
event bus)
● performance, regression, end2end, etc...
Terminology - Tests kinds
GUI
Integration Tests
(API,DB, etc)
Unit Tests
Terminology - Tests kinds
http://fabiopereira.me/blog/2012/03/05/testing-pyramid-a-case-study/
Hexagonal Architecture
https://herbertograca.com/tag/hexagonal-architecture/
Hexagonal Architecture
https://herbertograca.com/tag/hexagonal-architecture/
unit tests
Integration /
Gui
Tests
Tests rules
Unit tests:
● test ONLY by using units public methods (available through Facade)
● do not touch DB or HTTP, etc... check business logic only
● test as much logic as you can using unit tests (test pyramid)
Tests rules
Integration tests:
● setup DB to find out if you’re properly ‘integrated’ with it
● example: add movie with HTTP POST , save it into postgres, and verify that
everything can be retrieved properly (HTTP GET)
● never hit any live service (test server, etc)
Tests - stolen from BDD
How a test look like?
● use BDD like structure
● use given/when/then to distinguish test parts
● example!
BDD user story example
Scenario: As a user I cannot rent more than maximum number of movies at
the same time
Given a user previously rented one movie
And maximum rented movies count is 1
When user wants to rent second movie
Then user cannot rent second movie
Tests - Given
Section given:
● used to setup test data and state
● use only test-specific data (reuse global data for common tests)
● use Facade API for setup
○ don’t use repository directly - you can get into invalid logic due to logic change and test can still
pass
● stay minimal -> don’t create 20 objects to test pagination, etc
Tests - When
Section when:
● action that is being tested at state set up earlier
● single call of Facade API
Tests - Then
Section then:
● verify that things are working correctly
● use Facade to verify expectations
● test should have single reason to fail
Tests - Then
What makes your test great?
“ Test behaviour, not implementation”
== test most things using only your unit’s facade
Project time!
Things normally done wrong
“Adding new class is not a reason to add new test”
“Adding a method is not a reason to add new test”
Group tests properly
My DONT’s
● Don’t split logic into too many microservices too early
○ design so that you can extract it easily later
● Don’t let you tests run too slow
○ people will resist to write new (or just stop using TDD)
○ people will run them too rarely -> keep a quick feedback loop
● Don’t keep a test, that does not make you feel safe
○ just delete it
● Don’t create a test for each new class or method
My DONT’s
● Don’t mix layers of your application in tests
○ facade is used in each operation in given/when/then
● Don’t be afraid of same path covered in integration and unit test
○ they have different purpose and some are run more frequently
● Don’t overuse table tests
○ seen tests with 2-3 if’s inside based on which data is nil or not
○ better split to distinct tests
My DO’s
● test framework/technology is slow or hard to setup? -> change it!
○ example - Kafka Streams -> you can test everything without Kafka running
● use BDD-like given/when/then
○ make your IDE to generate that for you when creating new test
○ use multiple when/then with comment
● make test setup minimal
○ reuse variables
○ extract common things into methods
○ use builders
● after red/green/refactor - take a look at the name and place of a test
Biggest DO DO DO!
“ Test behaviour, not implementation”
Did it solve my problems?
● proper architecture
● hide logic behind a facade
● encapsulation kept in tests
● keeping given/when/then done right
== Tests immutable to refactor
When TDD is best?
When you have NO IDEA how you will code something!!!!!!!!!!!!!!!!
TDD done right - tests immutable to refactor
Lets do TDD!
Other stuff if there’s enough time
When to test single class/method?
● edge cases of simple logic
○ use table driven tests -> https://github.com/golang/go/wiki/TableDrivenTests
● For example some calculations based on numbers -> test all corner cases
When to use integration tests?
● heavily relying on DB queries
○ cannot unit test that
○ even then test using facade of your module
● test minimal integration cases, for example to check:
○ if you properly handle events?
○ are HTTP endpoint setup correctly?
○ are DTO’s properly serialized?
When to use mocks/stubs?
● communication with other units
● external clients (best if they provide them for you)
Thanks!
● Project: https://github.com/gmiejski/dvd-rental-tdd-example

More Related Content

PPTX
Mocking in python
PDF
Unit testing
KEY
Overview of Testing Talks at Pycon
PDF
Is this how you hate unit testing?
PPTX
Value of Unit Testing
PDF
Keeping code clean
PDF
Software Testing
PPTX
TDD with Python and App Engine
Mocking in python
Unit testing
Overview of Testing Talks at Pycon
Is this how you hate unit testing?
Value of Unit Testing
Keeping code clean
Software Testing
TDD with Python and App Engine

What's hot (20)

PDF
Unit testing in PHP
PDF
Refactoring Legacy Code
PDF
How to go about testing in React?
PDF
ATDD Using Robot Framework
PDF
Android Frameworks: Highlighting the Need for a Solid Development Framework 
PDF
Agile Programming Systems # TDD intro
PPTX
Test driving QML
PDF
POUG2019 - Test your PL/SQL - your database will love you
PPT
8 - Javascript unit testing framework
PDF
TDD for APIs @ Europython 2015, Bilbao by Michael Kuehne
POTX
Functional Tests. PHP Unconf 2016
PDF
Meetup React Sanca - 29/11/18 - React Testing
PDF
Unit Testing your React / Redux app (@BucharestJS)
PPTX
The Professional Programmer
PDF
TDD - Designing with Expectations, not Implementations
PPTX
PDF
Test-Driven Development with Plone
PDF
Unit testing (workshop)
PDF
Testing activities in CI/CD as exploratory tester
PPTX
Testing activities in continuous integration and continuous delivery as an ex...
Unit testing in PHP
Refactoring Legacy Code
How to go about testing in React?
ATDD Using Robot Framework
Android Frameworks: Highlighting the Need for a Solid Development Framework 
Agile Programming Systems # TDD intro
Test driving QML
POUG2019 - Test your PL/SQL - your database will love you
8 - Javascript unit testing framework
TDD for APIs @ Europython 2015, Bilbao by Michael Kuehne
Functional Tests. PHP Unconf 2016
Meetup React Sanca - 29/11/18 - React Testing
Unit Testing your React / Redux app (@BucharestJS)
The Professional Programmer
TDD - Designing with Expectations, not Implementations
Test-Driven Development with Plone
Unit testing (workshop)
Testing activities in CI/CD as exploratory tester
Testing activities in continuous integration and continuous delivery as an ex...
Ad

Similar to TDD done right - tests immutable to refactor (20)

PDF
Tests immutable when refactoring - SegFault Unconference Cracow 2019
PPTX
The tests are trying to tell you something@VoxxedBucharest.pptx
PPTX
Test-Driven Design Insights@DevoxxBE 2023.pptx
PDF
Testing, Learning and Professionalism — 20171214
PDF
(automatic) Testing: from business to university and back
PPT
XP through TDD
PDF
Testing and TDD - KoJUG
PPTX
Testing, a pragmatic approach
PDF
Testing: ¿what, how, why?
PPTX
Not all objects are equal - strategies for designing testable code
PDF
Intro To JavaScript Unit Testing - Ran Mizrahi
KEY
Best practices for writing good automated tests
KEY
Taking a Test Drive: iOS Dev UK guide to TDD
PDF
TDD — Are you sure you properly test code?
ODP
Writing useful automated tests for the single page applications you build
PDF
Testing survival Guide
PDF
How to write automated tests and don’t lose your mind by Dorian Sarnowski Scalac
PPTX
Unit testing & TDD concepts with best practice guidelines.
PPTX
XP in the full stack
PDF
Unit testing - An introduction
Tests immutable when refactoring - SegFault Unconference Cracow 2019
The tests are trying to tell you something@VoxxedBucharest.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptx
Testing, Learning and Professionalism — 20171214
(automatic) Testing: from business to university and back
XP through TDD
Testing and TDD - KoJUG
Testing, a pragmatic approach
Testing: ¿what, how, why?
Not all objects are equal - strategies for designing testable code
Intro To JavaScript Unit Testing - Ran Mizrahi
Best practices for writing good automated tests
Taking a Test Drive: iOS Dev UK guide to TDD
TDD — Are you sure you properly test code?
Writing useful automated tests for the single page applications you build
Testing survival Guide
How to write automated tests and don’t lose your mind by Dorian Sarnowski Scalac
Unit testing & TDD concepts with best practice guidelines.
XP in the full stack
Unit testing - An introduction
Ad

Recently uploaded (20)

PPTX
bas. eng. economics group 4 presentation 1.pptx
PPTX
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
PPTX
CYBER-CRIMES AND SECURITY A guide to understanding
PDF
Arduino robotics embedded978-1-4302-3184-4.pdf
PPTX
Strings in CPP - Strings in C++ are sequences of characters used to store and...
PPTX
additive manufacturing of ss316l using mig welding
PDF
Operating System & Kernel Study Guide-1 - converted.pdf
PDF
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
PDF
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
PDF
PPT on Performance Review to get promotions
DOCX
573137875-Attendance-Management-System-original
PDF
Well-logging-methods_new................
PPTX
UNIT 4 Total Quality Management .pptx
PDF
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
PDF
Model Code of Practice - Construction Work - 21102022 .pdf
PPTX
IOT PPTs Week 10 Lecture Material.pptx of NPTEL Smart Cities contd
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PPTX
Sustainable Sites - Green Building Construction
PPTX
Lecture Notes Electrical Wiring System Components
PPTX
Geodesy 1.pptx...............................................
bas. eng. economics group 4 presentation 1.pptx
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
CYBER-CRIMES AND SECURITY A guide to understanding
Arduino robotics embedded978-1-4302-3184-4.pdf
Strings in CPP - Strings in C++ are sequences of characters used to store and...
additive manufacturing of ss316l using mig welding
Operating System & Kernel Study Guide-1 - converted.pdf
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
PPT on Performance Review to get promotions
573137875-Attendance-Management-System-original
Well-logging-methods_new................
UNIT 4 Total Quality Management .pptx
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
Model Code of Practice - Construction Work - 21102022 .pdf
IOT PPTs Week 10 Lecture Material.pptx of NPTEL Smart Cities contd
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
Sustainable Sites - Green Building Construction
Lecture Notes Electrical Wiring System Components
Geodesy 1.pptx...............................................

TDD done right - tests immutable to refactor

  • 1. TDD done “right” - tests immutable to refactor Grzesiek Miejski
  • 3. Little about me ● Coding microservices for ~4 years ● Different languages and technologies: ○ now: Go, python ○ previously: Kotlin, Java ○ MongoDB, SQL, ElasticSearch, Cassandra, Kafka, RabbitMQ, blabla
  • 4. Are there not enough TDD materials already?
  • 5. My previous problems with tests ● changing business logic made me change tests a lot ● refactoring made me change tests ● applied “real” TDD only to the simplest code, with structure predicted upfront Is it worth trying then?
  • 7. But in what context? When my advices are applicable for me? ● everywhere where you want you software to last and be developed ● when building microservices, as this is what I do right now ● but would try love to try those practices in monolith written from start!
  • 8. Plan for presentation 1. About architecture 2. Unit and Facade 3. Unit and Integration tests 4. Unit tests in BDD style done right 5. Project immutable to refactor - example 6. DO’s and DONT’s 7. TDD goes live!
  • 9. Example project - movie renting site Simplified requirements: ● view available movies ● rent movie by user ● return movie by user ● prolong rented movie ● get movie recommendations ● ... (Normally should be some user stories or whatever)
  • 10. Example project - movie renting site Example user stories: ● As a user I cannot rent more than 2 movies at same time ● As a user I cannot rent movies for which I’m too young ● As a user I cannot rent more movies if I have a fee to pay for keeping to long ● As a user ...
  • 12. What is architecture? “Architecture is a set of rectangles and arrows, where: ● arrows are directed and ● there are no cycles Rectangles are on it’s own build from rectangles and arrows.“
  • 13. What is architecture? “Architecture is not discovered with unit testing, it must be done upfront”
  • 14. What is a unit? Units: ● units ~~ top-level rectangles ● communicate with other units ○ synchronously or asynchronously ● fulfills specific business cases (single responsibility) ○ made public to the world via a well designed API (called Facade later) ● can have completely different architecture (CQRS, actors, event sourcing...)
  • 16. Units API - Facade ● use Facade to export available actions
  • 18. Terminology - Tests kinds ● Unit ~~ module ~~ bounded context ○ module encapsulates it’s data and logic (use DTO to communicate) ○ modules are sliced vertically (all layers) ● Unit tests - checks your business logic (with no external dependencies) ● Integration tests - check your connection with external stuff (DB, HTTP api, event bus) ● performance, regression, end2end, etc...
  • 19. Terminology - Tests kinds GUI Integration Tests (API,DB, etc) Unit Tests
  • 20. Terminology - Tests kinds http://fabiopereira.me/blog/2012/03/05/testing-pyramid-a-case-study/
  • 23. Tests rules Unit tests: ● test ONLY by using units public methods (available through Facade) ● do not touch DB or HTTP, etc... check business logic only ● test as much logic as you can using unit tests (test pyramid)
  • 24. Tests rules Integration tests: ● setup DB to find out if you’re properly ‘integrated’ with it ● example: add movie with HTTP POST , save it into postgres, and verify that everything can be retrieved properly (HTTP GET) ● never hit any live service (test server, etc)
  • 25. Tests - stolen from BDD How a test look like? ● use BDD like structure ● use given/when/then to distinguish test parts ● example!
  • 26. BDD user story example Scenario: As a user I cannot rent more than maximum number of movies at the same time Given a user previously rented one movie And maximum rented movies count is 1 When user wants to rent second movie Then user cannot rent second movie
  • 27. Tests - Given Section given: ● used to setup test data and state ● use only test-specific data (reuse global data for common tests) ● use Facade API for setup ○ don’t use repository directly - you can get into invalid logic due to logic change and test can still pass ● stay minimal -> don’t create 20 objects to test pagination, etc
  • 28. Tests - When Section when: ● action that is being tested at state set up earlier ● single call of Facade API
  • 29. Tests - Then Section then: ● verify that things are working correctly ● use Facade to verify expectations ● test should have single reason to fail
  • 31. What makes your test great? “ Test behaviour, not implementation” == test most things using only your unit’s facade
  • 33. Things normally done wrong “Adding new class is not a reason to add new test” “Adding a method is not a reason to add new test”
  • 35. My DONT’s ● Don’t split logic into too many microservices too early ○ design so that you can extract it easily later ● Don’t let you tests run too slow ○ people will resist to write new (or just stop using TDD) ○ people will run them too rarely -> keep a quick feedback loop ● Don’t keep a test, that does not make you feel safe ○ just delete it ● Don’t create a test for each new class or method
  • 36. My DONT’s ● Don’t mix layers of your application in tests ○ facade is used in each operation in given/when/then ● Don’t be afraid of same path covered in integration and unit test ○ they have different purpose and some are run more frequently ● Don’t overuse table tests ○ seen tests with 2-3 if’s inside based on which data is nil or not ○ better split to distinct tests
  • 37. My DO’s ● test framework/technology is slow or hard to setup? -> change it! ○ example - Kafka Streams -> you can test everything without Kafka running ● use BDD-like given/when/then ○ make your IDE to generate that for you when creating new test ○ use multiple when/then with comment ● make test setup minimal ○ reuse variables ○ extract common things into methods ○ use builders ● after red/green/refactor - take a look at the name and place of a test
  • 38. Biggest DO DO DO! “ Test behaviour, not implementation”
  • 39. Did it solve my problems? ● proper architecture ● hide logic behind a facade ● encapsulation kept in tests ● keeping given/when/then done right == Tests immutable to refactor
  • 40. When TDD is best? When you have NO IDEA how you will code something!!!!!!!!!!!!!!!!
  • 43. Other stuff if there’s enough time
  • 44. When to test single class/method? ● edge cases of simple logic ○ use table driven tests -> https://github.com/golang/go/wiki/TableDrivenTests ● For example some calculations based on numbers -> test all corner cases
  • 45. When to use integration tests? ● heavily relying on DB queries ○ cannot unit test that ○ even then test using facade of your module ● test minimal integration cases, for example to check: ○ if you properly handle events? ○ are HTTP endpoint setup correctly? ○ are DTO’s properly serialized?
  • 46. When to use mocks/stubs? ● communication with other units ● external clients (best if they provide them for you)