Test Driven Development - coursehero/ch-react-workshop GitHub Wiki

What is it?

Test Driven Development is yet another software development methodology, and it may seem a bit backwards: you compose your test suite BEFORE you write the code to be tested!

Some have referred to this practice as "Red-Green Development" because once you've finished writing tests, they all fail (with the "green" or passing cases coming later, once you've finished writing the code).

TDD is not equivalent to only implementing unit tests (or "small" tests). To properly "do" TDD, you do not need to implement any particular type or size of test, but you will definitely want them to be automated (so the complete suite can run without manual involvement). The key to TDD is to properly cover all cases of situations and behaviors you want your code to handle.

What is its purpose?

The purpose of TDD is to make development of your code more streamlined, with fewer bugs/unknowns, and cleaner, more modular design. TDD does this by requiring the developer to consider every smallest use case ahead of time rather than writing a quick hack to accommodate a missed use case after the code is "done".

You could say that TDD is the formalization of the project/product specifications and requirements by way of test cases that serve as guideposts indicating "development is done when all tests pass". Of course, the definition of done is only as good as the detail and coverage of the test cases that were written. ;)

How do I do it?

There are many excellent tutorials and examples and step by step guides out there in teh interwebz - leverage these and learn! In short, though, you need to start with a solid, good-quality set of specifications and product requirements which can function both as user acceptance criteria and feed into the test cases for TDD. You can develop these with your Product team/leadership, or you can take some higher level requirements from Product and work with your teammates through "Story Mapping" to define the nitty-gritty cases.

(See Story Mapping for more info on how to create good, quality test cases from user stories.)

Once you have your test cases in total, you would determine how you'd implement them as your automated test suite. Some might be small or unit tests, some might be medium or even large tests. Some might be performance or scale/load tests. Ideally, it would be a cross section of types of tests, to help flesh out the entirety of the product requirements.

Succinctly, how you TDD is "Red, Green, Refactor". For each failing (🔴 red) test, you'd make some small code change in order to try to meet its requirement. Once passing (💚 green), you can take a moment to refactor the changes you made to get to green. Then, take another failing (red) test, and repeat the process until everything is green!

Baby steps, small bites, and more confidence that you're building software that complies with the requirements!

Advantages of TDD

  • Clarifies requirements with no need to scour an AR or scattered documentation/JIRA tickets for clues
  • Better than writing documentation (doesn't go out of date because you're running the tests constantly)
  • Forces you to follow good architecture principles (as architectural problems will surface more quickly)
  • Forces your code to be more modular (to be testable)
  • Encourages smaller steps
  • Makes collaboration easier (team members can make changes with confidence due to the automated tests)
  • Good for the team, good for the individual: you'll spend less time debugging, and write cleaner, simpler code
  • Catches "oops" mistakes immediately
  • Makes refactoring later easier (code is backed up by a complete set of good tests)
  • In the long run, really speeds up development (because when you're done, you're DONE with high confidence)

Disadvantages of TDD

  • Test suite must be maintained
  • Tests may not be completely deterministic if they rely on external dependencies
  • Some test cases may be difficult to implement
  • May feel like "we're going slower" initially, even though in the end, less development time is spent in total on a project
  • Writing good tests is an art form - coverage does not equal quality
  • The whole team has to engage in it for a project to really benefit from it
  • Can be challenging to learn
  • Hard to apply to existing legacy code

Other related topics

For more information about TDD, its pros and cons, here are some articles (with many points reflected above)

Next steps

"Best Practices" Re-read our best practices ;)

Thanks to Lisa Felten for contributing this article!