I have recently heard of Functional Testing over Unit Testing.
I understand that Unit Testing tests each of the possibilities of a given piece of code from its most atomic form. But what about Functional Testing?
This sounds to me like only testing if the code works, but is it as reliable as Unit Testing?
I've been told there was two school of thoughts for the matter. Certains would prefer Unit Testing, others Functional Testing.
Is there any good resources, links, books, any references or one of you all who can explain and elighten my path on the subject?
Thanks!
Jason's answer is correct. Different types of tests have different purposes, and can be layered for best results (good design, meeting specifications, reduced defects).
There is some overlap between these categories; unit tests can specify behavior, for instance.
And there are others; for more than most people care to know, see Software Testing.
One point people missed is that unit testing is testing pieces of code in isolation. Good unit tests don't hit the database, for instance. This has two advantages: it makes the tests run fast so you'll run them more often, and it forces you to write loosely coupled classes (better design).
You asked for resources; I recommend Roy Osherove's book The Art of Unit Testing with Examples in .NET. While no book is perfect, this one gives many excellent pointers on writing good tests.
EDIT: And for writing tests against existing software, nothing beats Michael Feathers' book Working Effectively with Legacy Code.
All the above are useful but they're not mutually exclusive. You should be doing most of them but the amount of time you spend on each part depends on the results you get from them, that's all. If your code is too modular to be easily unit tested, then spend your efforts on the functional tests. If you're writing a library of small components, spend your time on unit testing them, and if you're writing control systems for military missiles you should definitely be site acceptance testing them (as explosions even when it fails is fun :) )
Unit testing versus functional testing is not an
xor
, but rather anand
. Unit testing is about testing units in isolation while functional testing is about testing the whole in integration (do all the units works together properly?).Both are necessary components of good software engineering practices.
A Unit Test tests a piece of Code and confirms for a programmer that another piece of code is doing what it is supposed to. In Test Driven Development, the unit test is written first and observed to fail, before the code is written causing the test to pass. Programmers are interested in Unit Tests. Unit Test are quick to execute.
A Function Test tests your black box requirement and demonstrates that a piece of user functionality is in place. For example, if I press the big red button, the bell begins to ring. The functional test mightn't even be testing code. Perhaps there is a mechanical process that cause the bell to ring having pressed the button. Customers are interested in Functional Tests as they confirm that a high level process if working in a manner that they understand. They are often slow to execute.
Unit testing tests your code units (methods, etc) to make sure they do what you expect them to.
Functional testing tests your system design to make sure the pieces interact correctly. If you write a command that takes and int and returns a string and test it fully, you can be sure it works. But if you don't have system tests, you may never notice that the rest of the code thinks it can accept a null but it can't.
Both types of testing are important.
edit: To add a slightly different view to what gbjbaanb said:
Functional testing, also called System testing, aims at testing the complete system, and verifying the functional requirements are satisfied.
Unit testing aims at testing the "units", i.e. the functions or methods the system is build from in isolation. It's sometimes called Developer testing. Unit testing can be hard after the fact, that's why TDD writes the test before the code.
Those are complementary as the units can work independently and not when integrated all together, or they can pass the unit tests, and not fulfill all the product requirements.