tags:

views:

250

answers:

5

Hi,

I just want to know what is actual difference between unit tests and functional tests ? I am asking this because a unit test can also test a function right ?

+5  A: 

Unit Test - testing an individual unit, such as a method (function) in a class, with all dependencies mocked up.

Functional Test - AKA Integration Test, testing a slice of functionality in a system. This will test many methods and may interact with dependencies like Databases or Web Services.

bpapa
+13  A: 

Unit tests tell a developer that the code is doing things right; functional tests tell a developer that the code is doing the right things.

You can read more at Unit Testing versus Functional Testing


A well explained real-life analogy of unit testing and functional testing can be described as follows,

Many times the development of a system is likened to the building of a house. While this analogy isn't quite correct, we can extend it for the purposes of understanding the difference between unit and functional tests.

Unit testing is analogous to a building inspector visiting a house's construction site. He is focused on the various internal systems of the house, the foundation, framing, electrical, plumbing, and so on. He ensures (tests) that the parts of the house will work correctly and safely, that is, meet the building code.

Functional tests in this scenario are analogous to the homeowner visiting this same construction site. He assumes that the internal systems will behave appropriately, that the building inspector is performing his task. The homeowner is focused on what it will be like to live in this house. He is concerned with how the house looks, are the various rooms a comfortable size, does the house fit the family's needs, are the windows in a good spot to catch the morning sun.

The homeowner is performing functional tests on the house. He has the user's perspective.

The building inspector is performing unit tests on the house. He has the builder's perspective.


As a summary,

Unit Tests are written from a programmers perspective. They are made to ensure that a particular method (or a unit) of a class performs a set of specific tasks.

Functional Tests are written from the user's perspective. They ensure that the system is functioning as users are expecting it to.

Anthony Forloney
The quote is a bit vague for someone new to the concept.
fig
@fig-gnuton, I tried to elaborate to hopefully not make the description as vague. Inside the link they provide a good example, I could update the answer with the quote if you think that might help the OP.
Anthony Forloney
I decided to provide the quote, my mentality is: could help, couldn't hurt.
Anthony Forloney
+4  A: 

"Functional test" does not mean you are testing a function (method) in your code. It means, generally, that you are testing system functionality -- when I run foo file.txt at the command line, the lines in file.txt become reversed, perhaps. In contrast, a single unit test generally covers a single case of a single method -- length("hello") should return 5, and length("hi") should return 2.

See also IBM's take on the line between unit testing and functional testing.

Mark Rushakoff
A: 

The way I think of it is like this: A unit test establishes that the code does what you intended the code to do (e.g. you wanted to add parameter a and b, you in fact add them, and don't subtract them), functional tests test that all of the code works together to get a correct result, so that what you intended the code to do in fact gets the right result in the system.

Yishai
+4  A: 
  • A unit test tests an independent unit of behavior. What is a unit of behavior? It's the smallest piece of the system that can be independently unit tested. (This definition is actually circular, IOW it's really not a definition at all, but it seems to work quite well in practice, because you can sort-of understand it intuitively.)

  • A functional test tests an independent piece of functionality.


  • A unit of behavior is very small: while I absolutely dislike this stupid "one unit test per method" mantra, from a size perspective it is about right. A unit of behavior is something between a part of a method and maybe a couple of methods. At most an object, but not more than one.

  • A piece of functionality usually comprises many methods and cuts across several objects and often through multiple architectural layers.


  • A unit test would be something like: when I call the validate_country_code() function and pass it the country code 'ZZ' it should return false.

  • A functional test would be: when I fill out the shipping form with a country code of ZZ, I should be redirected to a help page which allows me to pick my country code out of a menu.


  • Unit tests are written by developers, for developers, from the developer's perspective.

  • Functional tests may be user facing, in which case they are written by developers together with users (or maybe with the right tools and right users even by the users themselves), for users, from the user's perspective. Or they may be developer facing (e.g. when they describe some internal piece of functionality that the user doesn't care about), in which case they are written by developers, for developers, but still from the user's perspective.


  • In the former case, the functional tests may also serve as acceptance tests and as an executable encoding of functional requirements or a functional specification, in the latter case, they may also serve as integration tests.

  • Unit tests change frequently, functional tests should never change within a major release.


Jörg W Mittag
+1: Best programming-level examples in an answer.
Donal Fellows
@Jörg W Mittag: excellent answer! one thing - "functional tests should never change within a major release" why is that?
Lazer
@Lazer The idea here is that a major release goes along with large changes in functionality, where as a minor release would be smaller updates that don't change the functionality (and hence don't change the functional tests)
cdeszaq
@Lazer, @cdeszaq: In many projects, a change in the major version number is used to indicate backwards-incompatibility and OTOH if the major version does *not* change, backwards-compatibility is *guaranteed*. What does "backwards-compatibility" mean? It means "does not change user-visible behavior". And the functional tests are an executable encoding of the specification of the user-visible behavior. So, if the major number doesn't change, then the functional tests aren't allowed to change either and conversely, if the functional tets *do* change, then the major number *must* change as well.
Jörg W Mittag
Note: I didn't say anything about *adding* functional tests! Whether or not adding functionality that wasn't there before constitutes a backwards-incompatible change, depends on the project. For end-user software, probably not. But for a programming language? Maybe: introducing a new keyword, for example, makes currently working programs that happen to use that keyword as a variable name invalid, and thus is a backwards-incompatible change.
Jörg W Mittag