Theory
Alternatively : you can watch the slides about the theory
TDD
TDD (Test Driven Development) is cool!
It makes sure we develop the right thing, step by step
Short version
flowchart TB start([Start]) ==> red([Write only 1 failing test]) ==> green([Make all tests pass]) ==> refactor([Refactor]) ==> finish([Finish]) refactor -.->|Incomplete ?| red classDef red_phase font-weight:bold,color:black,fill:coral; class red red_phase classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase classDef refactor_phase font-weight:bold,color:black,fill:#668cff; class refactor refactor_phase
Long version
flowchart TB subgraph red[Red] direction LR fix_layout(( )) ==> write_a_test write_a_test[Write only 1 failing test] ==> run_tests{{Run tests}} run_tests -.->|Pass\nWrite another test| write_a_test end start([Start]) === fix_layout run_tests ==>|Fail| green([Green]) classDef red_phase font-weight:bold,color:black,fill:coral; class red red_phase classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase classDef refactor_phase font-weight:bold,color:black,fill:#668cff; class refactor refactor_phase classDef fix_layout stroke:white,fill:transparent; class fix_layout fix_layout
flowchart TB subgraph green[Green] direction LR fix_layout(( )) ==> write_the_minimum_code write_the_minimum_code[Write the minimum code\nto make all tests pass] ==> run_tests{{Run tests}} run_tests -.->|Fail\nTry something else| write_the_minimum_code end red([Red]) === fix_layout run_tests ==>|Pass| refactor([Refactor]) classDef red_phase font-weight:bold,color:black,fill:coral; class red red_phase classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase classDef refactor_phase font-weight:bold,color:black,fill:#668cff; class refactor refactor_phase classDef fix_layout stroke:white,fill:transparent; class fix_layout fix_layout
flowchart TB subgraph refactor[Refactor] direction LR rewrite_code[Rewrite code\nwithout changing the behavior] ==> run_tests{{Run tests}} -.->|Pass\nAnother things to refactor ?| rewrite_code run_tests -->|Fail\nChange something else| rewrite_code end green([Green]) ==> rewrite_code run_tests ==>|Pass| finish([Finish]) run_tests -.->|Pass\nAnother feature to add ?| red([Red]) classDef red_phase font-weight:bold,color:black,fill:coral; class red red_phase classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase classDef refactor_phase font-weight:bold,color:black,fill:#668cff; class refactor refactor_phase classDef fix_layout stroke:white,fill:transparent; class fix_layout fix_layout
TCR
TCR (test && commit || revert
) is cool!
It encourages doing baby steps, reducing the waste when we are wrong
flowchart TB gamble{{Gambling on test results}} gamble ==>|Pass| commit(Commit) gamble -->|Fail| revert(Revert)
flowchart TB start([Start]) ==> green([Change some code]) ==> finish([Finish]) green -.->|Incomplete ?| green classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase
But it doesn't allow us to see the tests failing
So:
-
Maybe we test nothing (assert forgotten)
def test_should_be_Buzz_given_5(): input = 5 actual = fizz_buzz(input) # Oops! Assert has been forgotten
-
Maybe we are testing something that is not the thing we should be testing
it("should be Fizz given 3", () => { const input = 3; const actual = fizzBuzz(input); expect(input).toBe("Fizz"); // Oops! Asserts on the input value instead of the actual value });
Detailed view
flowchart TB subgraph green[Green] direction TB start([Start]) ==> change_code[Change some code] ==> run_tests{{"Run tests\n<code>test && commit || revert</code>"}} ==>|Pass| commit(Commit) ==> finish([Finish]) commit -->|Another things to change ?| change_code run_tests -.->|Fail| revert(Revert) -.->|Try something else| change_code end classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase
TCRDD
TCRDD = TCR + TDD
TCRDD blends the constraints of the two methods to benefit from their advantages
flowchart TB red{{Write only 1 failing test}} green{{Make all tests pass}} refactor{{Refactor}} red ==>|Fail| red_commit(Commit) ==> green green ==>|Pass| green_commit(Commit) ==> refactor refactor ==>|Pass| refactor_commit(Commit) red -->|Pass| red_revert(Revert) --> red green -->|Fail| green_revert(Revert) --> green refactor -->|Fail| refactor_revert(Revert) --> refactor classDef red_phase font-weight:bold,color:black,fill:coral; class red red_phase classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase classDef refactor_phase font-weight:bold,color:black,fill:#668cff; class refactor refactor_phase
flowchart TB subgraph red[Red] direction LR fix_layout(( )) ==> write_a_test write_a_test[Write only 1 test] ==> gamble[/Gamble that the test fail\n<code>git gamble --red</code>/] ==> run_tests{{Actually run tests}} ==>|Fail| commit(Commit) run_tests -->|Pass| revert(Revert) -->|Write another test| write_a_test end start([Start]) ==> fix_layout commit ==> green([Green]) classDef red_phase font-weight:bold,color:black,fill:coral; class red red_phase classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase classDef refactor_phase font-weight:bold,color:black,fill:#668cff; class refactor refactor_phase classDef fix_layout stroke:white,fill:transparent; class fix_layout fix_layout
flowchart TB subgraph green[Green] direction LR fix_layout(( )) ==> write_the_minimum_code write_the_minimum_code[Write the minimum code] ==> gamble[/Gamble that the tests pass\n<code>git gamble --green</code>/] ==> run_tests{{Actually run tests}} ==>|Pass| commit(Commit) run_tests -->|Fail| revert(Revert) -->|Try something else| write_the_minimum_code end red([Red]) ==> fix_layout commit ==> refactor([Refactor]) classDef red_phase font-weight:bold,color:black,fill:coral; class red red_phase classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase classDef refactor_phase font-weight:bold,color:black,fill:#668cff; class refactor refactor_phase classDef fix_layout stroke:white,fill:transparent; class fix_layout fix_layout
flowchart TB subgraph refactor[Refactor] direction LR rewrite_code[Rewrite code\nwithout changing the behavior] ==> gamble[/Gamble that the tests pass\n<code>git gamble --refactor</code>/] ==> run_tests{{Actually run tests}} ==>|Pass| commit(Commit) -.->|Another things to refactor ?| rewrite_code run_tests -->|Fail| revert(Revert) -->|Change something else| rewrite_code end green([Green]) ==> rewrite_code commit ==> finish([Finish]) commit -.->|Another feature to add ?| red([Red]) classDef red_phase font-weight:bold,color:black,fill:coral; class red red_phase classDef green_phase font-weight:bold,color:black,fill:#1cba1c; class green green_phase classDef refactor_phase font-weight:bold,color:black,fill:#668cff; class refactor refactor_phase classDef fix_layout stroke:white,fill:transparent; class fix_layout fix_layout
git-gamble
is a tool that helps to use the TCRDD method