TDD
My thoughts on Test Driven Development
definition
- tests are small examples of how things should work
- ideally one test checks single requirement
- test -> red -> implementation -> green
- refactor?
why?
- no developer is able to keep all requirements in memory
- eventually bugs will slip into the code
- test won’t fail without reason
- stability of the system
- sleep well at night
- confidence
- no pain refactoring, especially when changing implementation of some critical service
- quick feedback loop
- no deployments and manual clicking needed to add new features
- testable code is usually more clean and better structured
- legacy code = not tested code in my book, noone like rewriting legacy stuff so...
myths
it takes too much time
- saves time for debugging and bug fixing
- saves time for development deployments
- it makes your work more structured and less chaotic
- it makes returning to project after a long break way easier and less stressful
writing tests is difficult and complex
- it may be when you write tests after implementation because resulting code is not testable/structured wrong
- it's easy when you write tests first and take small steps
- changing mindset may be painful, but it's well worth it
everything can be tested
- false, just use your judgement and test business logic that matters (eventually you will be testing small stuff too, it's that addicting :))
tdd replaces architecture of the app
- architecture/design needs to be there
- architecture gives the team boundaries they need, so that they may focus on driving the implementation with unit tests
- what tdd gives you is early feedback about your architectural and design decisions
tdd replaces qa
- NO, it doesn't
- it's just a tool at developer disposal that, when applied correctly, gives a lot of advantages described above
how?
- thinking about tests first can be painful at the beginning, but becomes second nature quite soon
- every mainstream language i know has some xUnit type of library, your favourite language have it as well
- keep tests simple, new test = next smallest step on your way to full feature
- keep tests dumb, just test states, no logic inside tests
- use mocks for dependencies (develop with use of interfaces, so that implementation can be swapped!)
- it's a good idea to create a few project-wide abstract classes for unit tests, as they will be reused a lot, create little DSL
- too much 'verify' calls is a code smell
- too much asserts in single method is a code smell (debatable tho)
tips
- if there is a bug, write test first to reproduce it, then fix - this will make any regression bug to not appear again
- time is a dependency, create time service and use mocking techniques to test time related code
- after taking a break it's easy to lose context of what you are trying to do with your code, just leave one single test breaking and it will be easier to pick up your job later on and get into 'THE ZONE' faster
- gamification - treat your tests as a progress metric, do small celebrations on each milestone (like 50 tests per day or project having 100/500/1000 tests), brag on company's chat about it
- share with other developers how your test suite just saved you a lot of debugging or introducing some critical bug at production, this builds team confidence (i personally had a few stories where tests really helped keep everything in good condition despite me thinking i know better and nothing should fail after my changes)
let's code