views:

490

answers:

6

I just had a conversation with my lead developer who disagreed that unit tests are all that necessary or important. In his view, functional tests with a high enough code coverage should be enough since any inner refactorings (interface changes, etc.) will not lead to the tests being needed to be rewritten or looked over again.

I tried explaining but didn't get very far, and thought you guys could do better. ;-) So...

What are some good reasons to unit test code that functional tests don't offer? What dangers are there if all you have are functional tests?

Edit #1 Thanks for all the great answers. I wanted to add that by functional tests I don't mean only tests on the entire product, but rather also tests on modules within the product, just not on the low level of a unit test with mocking if necessary, etc. Note also that our functional tests are automatic, and are continuously running, but they just take longer than unit tests (which is one of the big advantages of unit tests).

I like the brick vs. house example. I guess what my lead developer is saying is testing the walls of the house is enough, you don't need to test the individual bricks... :-)

+11  A: 

Off the top of my head

  • Unit tests are repeatable without effort. Write once, run thousands of times, no human effort required, and much faster feedback than you get from a functional test
  • Unit tests test small units, so immediately point to the correct "sector" in which the error occurs. Functional tests point out errors, but they can be caused by plenty of modules, even in co-operation.
  • I'd hardly call an interface change "an inner refactoring". Interface changes tend to break a lot of code, and (in my opinion) force a new test loop rather than none.
NR
I agree with the second two points - but functional tests can be automated too.
slim
@slim: While they can they are more likely to need refactored between releases IMHO
tloach
@tloach - Not sure I understand. Surely functional requirements are more static than internal implementation?
slim
true, functional tests can be automated as well (we do it anyway for a limited set), but in the end you will need a human approval
NR
@tloach - when automated functional test script needs to be frefctored then manual functional test script must be refactored also.
yoosiba
@NR - unit tests need approval human also. It just happens that usually developer writes them and approves them if code responds properly. But you should have review and human approval for them otherwise one can in all tests write assert(true) and have all tests passing.
yoosiba
+3  A: 

It can be a lot more difficult to find the source of problems if a functional test fails, because you're effectively testing the entire codebase every time. By contrast, unit tests compartmentalize the potential problem areas. If all the other unit tests succeed but this one, you have an assurance that the problem is in the code you're testing and not elsewhere.

Adam Bellaire
+1  A: 

Bugs should be caught as soon as possible in the development cycle - having bugs move from design to code, or code to test, or (hopefully not) test to production increases the cost and time required to fix it.

Our shop enforces unit testing for that reason alone (I'm sure there are other reasons but that's enough for us).

paxdiablo
+6  A: 

unit tests are for devs to see where the code failed

functional tests are for the business to see if the code does what they asked for

matpalm
+3  A: 

unit tests are for devs to see where the code failed

functional tests are for the business to see if the code does what they asked for

unit tests are checking that you've manufactured your bricks correctly

functional tests are checking that the house meets the customer's needs.

They're different things, but the latter will be much easier, if the former has been carried out.

belugabob
A: 

If you use a pure Extreme Programing / Agile Development methodology the Unit tests are always required as they are the requirements for development.

In pure XP/Agile one makes all requirements based on the tests which are going to be performed to the application

  • Functional tests - Generate functional requirements.
  • Unit tests - Generate functions or object requirements.

Other than that Unit testing can be used to keep a persistent track of function requirements.

i.e. If you need to change the working way of a function but the input fields and output keep untouched. Then unit testing is the best way to keep tracking of possible problems as you only need to run the tests.

fmsf
Isn't it usually the other way around - requirements, and then tests?
sheepsimulator