Gradle is such an interesting build tool that it prompted me to look at Spock and JUnit — which I’ve never done before. What is the basic workflow with TDD?
My approach has been to do frequent builds, slightly less frequent clean builds, and to run the application as much as possible. Certainly, there are entire books on TDD, but my most basic question is about the workflow.
Instead of working in src/main/java
, most of the coding is done in the test
directory? This, to me, intuitively, seems wrong. With version control, why have the duplicate directory structure? It can only lead to discrepancies between src/main
and src/test
which must be resolved manually.
Why not just work in one branch, then, when complete, create a branch without the tests?
What do you do when you want to actually run the application?
4
The basic workflow for TDD is commonly known as “Red; Green; Refactor”:
- Red: Write a failing test
- Green: Modify the code to make that test pass (without any existing tests failing)
- Refactor: Tidy up the code to better incorporate the change.
There are numerous resources that explain this process in details, eg The Cycles of TDD
It’s unclear to me as to what the relevance of your comments re src/main
and src/test
and branches are to this process. However, regarding builds: you need to do a full build and re-run of all tests after each of the above three steps. The tests remain part of your source, always, as the whole idea is to re-run all tests after all changes to ensure you haven’t broken an unrelated test (and thus feature) with a change.
4
You will normally keep your tests in a separate folder hierarchy as they usually aren’t part of the binary you ship, and it’s just simpler to not mix them up, but you keep them in the same repo and branch because they belong together in source.
As for where you work, TDD means Test Driven Development, which means you first write a (small) test for the feature you want your code to provide. You run it and watch it fail; red. You then implement the functionally in the “simplest possible way” until the test succeeds; green. You can then optionally refactor the code while keeping the test green. You then go back to writing another failing test, and so on.
By adding tests for additional features this way, and implementing the features in small increments, you reduce some of your guesswork that normally happens when you try to write the code before the tests. Tests in TDD represents a future user of your API, even before the code exists. Thus you’re less likely to write code that’s not needed, with a reasonable API, while constantly guarding any the code you’ve already written.
2
The tests aren’t there to ensure you write the code you want to write. They are there to ensure that three years from now, you don’t accidentally change the way the code works through a seemingly unrelated change, causing unintelligible defects.
Tests are insurance against the future. Never remove the tests.
2