4 ms·
tldr; read kent beck's original book on the topic before you form your opinion. TDD is not a silver bullet and it's not 100% required to write quality software.
by dczmer 10y ago
tldr; read kent beck's original book on the topic before you form your opinion. TDD is not a silver bullet and it's not 100% required to write quality software. but it is a useful tool, and you probably are doing it wrong. if someone taught you at work or school, there is a good chance they were doing it wrong. if you still don't see the point after kent's book and the video that i've linked below, then at least you know the most common arguments for both sides now.
i'm a proponent of TDD and unit testing but i don't TDD all the things. there is, as in all things, a balanced to be achieved between test coverage and delivery time. some parts of the system - primarily the business logic - need thorough testing. other parts of the system, especially those that don't change often, can require less testing. additionally, many people and organizations misinterpret the basic concept behind what Kent Beck describes in his book and end up implementing lots of complicated, brittle tests that eat development time and slow down the entire process.
#1 read Kent's book. seriously, do this now. don't just assume you understand TDD because it sounds so obviously simple
#2 watch Ian Cooper's excellent talk: TDD Where Did it All Go Wrong? https://vimeo.com/68375232 https://vimeo.com/68375232
i will say that, even after nearly a decade of writing tests, i didn't really understand why my tests were so brittle until i watched #2. turns out i didn't realize what a 'unit' _really_ was, WRT writing tests.
now that you know how and what to test, a few tips:
#1 keep "unit tests" separate from "integration tests":
- unit tests do not do any actual I/O, run very fast, test "units" in isolation
- integration/system tests run over entire systems or sub-systems, rather than isolated units
- actually do I/O: db, disk, etc
- are slow, but you don't need that many of them if you have good unit test coverage
- this point will be made more clear in the video linked above
#2 write tests to an interface, not to an implementation
- when you write a test that depends on implementation details, it will be brittle and cause trouble when that implementation changes
- when you write a test to an interface, the implementation details should be irrelevant (to a degree). you care about the "what" (inputs/outputs/exceptions), not the "how"
#3 inversion of control and dependency injection are your friends
- the video linked above should give you an idea of what i'm talking about, WRT hexagonal architecture
- if you create an object in the function under test, it's hard to manipulate that object to drive the test
- if the function under test accepts that object as a param, you can configure it before calling the test or replace it with a mock object
#4 be wary of overuse of mocks!
- when you end up with tests that are just lots of mock expectations describing the interaction between two objects, you are testing implementation!
- lose the mocks and write a system test instead
#5 tests are production code! you will need to put the same effort into making them readable and maintainable. you might even have to write tests for some of your test support code
- dczmer 10y agoomg l2format