title | author | date | css |
---|---|---|---|
Introduction into test-driven development |
Zeger Hendrikse |
2023-09-29 |
css/custom.css |
Dave Farley — the culture of TDD
- Test Suite => specification
- Test => scenario
- Structure tests around "Given, When, Then"
# spec/string_calculator_spec.rb
describe StringCalculator do
describe ".add" do
context "given an empty string" do
it "returns zero" do
expect(StringCalculator.add("")).to eq(0)
end
end
end
end
<iframe width="100%" height="500" src="//jsfiddle.net/zhendrikse/bu7tv1kp/3/embedded/js,result/dark/" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0">
(c) Lasse Koskela
Bob Martin: Test Contra-variance
The structure of the tests must not reflect the structure of the production code because that much coupling makes the system fragile and obstructs refactoring. Rather, the structure of the tests must be independently designed so as to minimize the coupling to the production code.
Why? ==> Because we specify!
![]() |
|
Martin Fowler: refactoring
... is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior
Small increments
We are not allowed to write:
- any production code before you have a failing test
- any more of a test than is sufficient to fail (also compilation!)
- any more code than is sufficient to pass the one failing unit test
- Passes the tests
- Reveals intention (Clean code) → game of life:
(defn next-generation-of [game]
(map #(to-living-cell
(which-both
is-dead?
(has-exactly-three? (living-neighbours-in game))) %)
(map #(to-dead-cell
(which-both
is-alive?
(which-either
(has-less-than-two? (living-neighbours-in game))
(has-more-than-three? (living-neighbours-in game)))) %) game)))
As a worker in a restaurant
I want to place my clean plates on a stack
so that I always have plates available to serve dishes
- Start with an empty stack
- Define pop on an empty stack
- Define push on an empty stack
- Define pop on a non-empty stack
- Define multiple pushes and pops
Credits to Kent Beck and Eisenhower!
<iframe width="100%" height="700" src="//replit.com/@zwh/Scrumblr?embed=true" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0">
- Let's do this in Javascript!
- Let's do this in Python!
- Let's do this in Typescript!
- Let's do this in Java
- Let's do this in C#
- Let's do this in C++
- Tests become more specific, code more generic
- TBD becomes a no-brainer
- Difficulty is "postponing the gold"
- Contravariant test suites
- 1, 2, N
- Tests grouped according to shared set-up
- What is still left to test?
- The Clean Architecture: how to cope with dependencies on external systems
- Developer tests his own code: the nightmare of every auditor!
Coding + testing are the same activity
The importance of test contra-variance
See how TDD is done in practice
Motivation to learn & practice more TDD
- Questions are allowed at all times
-
The goal is to illustrate the TDD process
- The goal is not to write the best
- Javascript ever
- Python ever
- ...
- User story is not the most realistic either
- The goal is not to write the best
- Unit test === Functional test
- Unit tests test the smallest functional unit
- Practicing TDD/BDD ==> test contra-variance
- xUnit tests ≠ TDD
- Unit test === Functional test