73

From reading the descriptions, I understand that in TDD tests are done prior to writing the function and in Unit Testing, its done afterwards.

Is this the main difference, or the two terms can't even be compared as such. Perhaps, Unit Testing is an integrated part of TDD.

7 Answers 7

116

Unit Testing refers to what you are testing, TDD to when you are testing.

The two are orthogonal.

Unit Testing means, well, testing individual units of behavior. An individual unit of behavior is the smallest possible unit of behavior that can be individually tested in isolation. (I know that those two definitions are circular, but they seem to work out quite well in practice.)

You can write unit tests before you write your code, after you write your code or while you write your code.

TDD means (again, kind of obvious) letting your tests drive your development (and your design). You can do that with unit tests, functional tests and acceptance tests. Usually, you use all three.

The most important part of TDD is the middle D. You let the tests drive you. The tests tell you what to do, what to do next, when you are done. They tell you what the API is going to be, what the design is. (This is important: TDD is not about writing tests first. There are plenty of projects that write tests first but don't practice TDD. Writing tests first is simply a prerequisite for being able to let the tests drive the development.)

7
  • 1
    Great Answer. would add...TDD is when you let tests to push you and features to pull your development efforts...
    – Martin
    Feb 5, 2015 at 10:20
  • They are not orthogonal though. You can't have TDD without unit tests.
    – JacquesB
    Dec 1, 2015 at 7:39
  • 1
    @JacquesB, why? Our tests are not what you'd call unit tests by any definition, they depend too much on infrastructure and other components, but we still have enough observability that we -- well at least some of us -- are doing TDD. Dec 1, 2015 at 9:02
  • 5
    @AndrewWillems: TDD means that the tests drive the development. You don't decide what the design looks like, the tests tell you. You don't decide what to work on next, the tests tell you. You don't decide when you're finished, the tests tell you. It is perfectly possible to write tests first, and then ignore everything they are telling you. For example, you could write tests first, but then keep on writing code even after all tests are green. So, in other words: you write tests first, but you treat them just as tests, and don't let them drive the development. Feb 12, 2017 at 9:56
  • 1
    @JörgWMittag You might be right in a purist way of looking at it, but you also know that TDD is not black and white. Any sane use of TDD would not let the tests drive the development completely, and tests definitely do not always decide what the design looks like (maybe unit tests can partly do this, but not tests at a higher abstraction level). What about refactoring? Which is a very important aspect of TDD. Also in the real world there is no such thing as 'ignore everything the test is telling you'. By definition, if you write tests first, you use 'some form of TDD'.
    – NickL
    Mar 25, 2017 at 20:39
23

Unit Testing is a component of Test Driven Development

You can do unit testing without doing test driven development. However you can't do test driven development without using unit tests.

When you do traditional unit testing, you write test after you wrote your code.

Test driven development approach is to write unit test before writing code.

Most interesting advantages of TDD (IMHO) comparing to simple Unit Testing:

  • Code is fully tested code upfront. It's painless testing.
  • It forces you to design your classes correctly.
  • It also forces you to keep it simple stupid.
  • The cycle of Red-Green-Refactor is the absolute procrastination killer!
4
  • Have you missed "unit" on purpose in the statment:"However you can't do test driven development without using testing." ?
    – ratkok
    Jun 30, 2011 at 4:43
  • @ratkok: no that was not on purpose. Let me fix that.
    – user2567
    Jun 30, 2011 at 9:23
  • I like this definition the best. It's better put together in words than other answers.
    – Tek
    Jan 8, 2015 at 20:29
  • 3
    Arguably, you can do TDD using module-tests or system-tests rather than true unit-tests. I wouldn't advise it, as you lose much of the benefit if the tests take too long to run, but it's not impossible. Jun 15, 2016 at 9:17
14

TDD and Unit Testing are two very specific terms which often get misused.

TDD is writing a test which will fail, then writing the minimum amount of code required to make it run, then refactoring the code to make it clean. This is done in cycles, fail -> pass -> refactor, adding a new test for each known requirement for the code. More recently, TDD has become even more specifically about writing unit tests in that cycle, to distinguish it from ATDD (a subset of BDD) which is writing acceptance tests in a similar cycle.

Unit Testing is about testing a code in small, isolated units. The common confusion here is to think that if you're using a unit testing tool, such as xUnit or Rspec, to run tests that you are writing unit tests. This is not necessarily true. Those tools can be used to run say tests using the Selenium framework - in that case you are writing acceptance tests using a unit test runner. Unit tests are very specifically tests which focus on a small piece of logic, isolated from everything else for the sake of speed (so that you can run them often and get fast feedback on new bugs).

1
  • 1
    The JUnit tests for JUnit itself are a good example: a significant portion of those are functional tests and acceptance tests, not unit tests, even though they are written in JUnit. Also, the creator of JUnit also happens to be the creator of TDD, and JUnit was developed using TDD using a significant amount of functional tests and acceptance tests. Acceptance testing is an integral part of TDD. Mar 19, 2011 at 15:08
6

TDD is the approach of writing the test cases before development as you said and then the developer writes the code to pass the test cases. Unit Testing is a term used to describe a narrow scoped type of testing other than system testing, integration testing and acceptance testing.

3

TDD is a philosophical approach to writing code: write the tests first. The tests you write are unit tests.

1

The way I separate the two is to consider that TDD is less about testing, and more about designing the code. Unit tests are then used to set the expectations for the end code. When the end code is written, and passes tests (specifications), you have code that was designed using tests.

1

All excellent answers. I would only add that unit testing tends to regard the 'unit' as a small component, while TDD scales up to include integration and acceptance tests.

(Some TDD variants regard the 'unit' as the smallest incremental step towards the desired functionality...)

5
  • they should, but in my experience in reality they don't. Companies/groups say they do TDD, when all they do is force programmers to go test-first with jUnit tests, then use the fact that everything was already tested during development to do away with (or greatly reduce) QA and integration testing.
    – jwenting
    Mar 19, 2011 at 21:31
  • 2
    @jwenting don't blame the methodology for the shortcomings of those that claim to practice it. any tool can be misused Mar 20, 2011 at 1:56
  • 1
    I don't, but you have to realise that there's a big difference between what TDD is in theory and what it is in reality. And as most people (OP included) probably only ever see the reality, the difference should be pointed out to them.
    – jwenting
    Mar 20, 2011 at 8:40
  • Considering that TDD is about design - why would it include acceptance testing? how would it "drive" the design? Aug 24, 2019 at 12:07
  • 1
    @VitaliiIsaenko acceptance tests provide the highest-level scoping for designs Aug 26, 2019 at 21:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.