429

What is the difference between unit tests and functional tests? Can a unit test also test a function?

Renan Araújo
  • 3,266
  • 11
  • 32
  • 46
mousey
  • 10,655
  • 15
  • 47
  • 54
  • 2
    See also: http://stackoverflow.com/questions/927857/confusion-leave-out-functional-tests-that-cover-same-ground-as-unit-tests and http://stackoverflow.com/questions/2230286/unit-testing-or-functional-testing –  Apr 30 '10 at 02:13
  • See also: [Difference between functional test and end-to-end test](https://stackoverflow.com/q/48762575/562769) – Martin Thoma Apr 30 '20 at 10:19

16 Answers16

533

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.

Community
  • 1
  • 1
Anthony Forloney
  • 84,001
  • 14
  • 111
  • 112
  • 21
    The quote is a bit vague for someone new to the concept. –  Apr 30 '10 at 02:15
  • 2
    @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 Apr 30 '10 at 02:20
  • 164
    Perhaps another way to say it would be, "Unit test make sure the code does what the programmer wants, Functional tests make sure the programmer is doing what the customer wants"? – JS. Apr 15 '11 at 17:36
  • 3
    I like that but would adjust it to. A **Functional Test** makes sure the application allows the user to perform an action. A **Unit Test** makes sure the code behaves how the programmer expects. – Adam Dec 06 '16 at 03:53
  • 2
    Isn't what the programmer wants adheres to what the end user wants? Why writing a test which does not serve what the customer expects? – O.Badr Feb 02 '18 at 18:35
  • In what category do you put automated tests developed with Selenium? – Fernando Gabrieli Mar 08 '19 at 02:59
  • 1
    doesn't that make unit tests kind of redundant? Since the passing of functional tests would mean unit tests are working as well? – daisura99 Jul 06 '19 at 06:10
265

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
  • 21,107
  • 23
  • 95
  • 147
  • 189
    Let me disagree with "AKA Integration Test". An integration test, checks the integration between 2 or more systems/subsystems in your code. Example, checking a SQL query through an ORM, checks that ORM and database work well together. Functional Tests AKA End to End IMHO. – graffic Mar 26 '14 at 09:10
  • 10
    I agree with @graffic Functional Test != Integration Test You must be confusing "integration" of sub-components of system within each other such as persisting state etc. But in general sense Integration testing has a much wider scope. – nabster Mar 13 '15 at 19:41
  • 5
    Nope, wasn't confused about anything. – bpapa Jun 05 '15 at 20:28
  • 4
    Integration Test IS-A Functional Test. But not vice versa. Google "functional and non functional testing" and check the "Images". – Andrejs Jun 01 '16 at 09:07
  • In which category does the this quickcheck library falls. As it takes a different approach for testing. – pannu Aug 10 '17 at 06:06
  • @pannu no idea what that is, you should ask a new question – bpapa Aug 10 '17 at 13:07
  • 7
    This answer is simply WRONG! Functional testing is NOT even close to integration test.. – sotn Jul 19 '18 at 09:02
146
  • 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.


Lazer
  • 79,569
  • 109
  • 264
  • 349
Jörg W Mittag
  • 337,159
  • 71
  • 413
  • 614
  • excellent answer! one thing - "functional tests should never change within a major release" why is that? – Lazer May 12 '10 at 10:06
  • @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 Jul 06 '10 at 14:31
  • 5
    @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 Jul 06 '10 at 17:47
  • 2
    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 Jul 06 '10 at 17:49
  • 3
    @JörgWMittag love that idea: 'functional tests are an executable encoding of the specification of the user-visible behavior'... whether or not other super-experts actually agree, it helps me with the original question, to wit "the difference between 'em" – mike rodent Aug 25 '15 at 13:34
  • @mikerodent: This was actually used in Merb, which is where I got the idea from. When a release was made, the functional tests were moved into a subdirectory, say, `tests/functional/1.0.0`, and it was not allowed to change those. All future point releases, say, 1.0.3 had to pass all the tests in 1.0.0. For minor releases, say, 1.2.0, you could only *add* new tests, not remove or change old ones, you had to pass all tests in 1.0.0, 1.1.0, 1.2.0. Removing or changing a test necessitated a major release (2.0.0). Essentially, this ties the definitions of "bugfix", "backwards-compatible addition" … – Jörg W Mittag Aug 25 '15 at 13:40
  • … and "breaking change" to the test suites, and makes it an objective, verifiable distinction. – Jörg W Mittag Aug 25 '15 at 13:40
  • @mikerodent: There's also the idea that an "acceptance test is a functional test you get paid for". I.e., acceptance tests are a subset of functional tests that encode the acceptance criteria of your customer, and every passing acceptance test means fulfilling an acceptance criterion, or put another way, an objectively verifiable step towards fulfilling your contract. This works best if your customer is technical enough, and your test framework is non-technical enough, that the customer can actually read the tests and confirm, "yes, that it is what I want". – Jörg W Mittag Aug 25 '15 at 13:45
  • I get it... except I'm a non-professional, so don't expect to get paid for anything any time soon. The upside being that I don't have customers who, inevitably, are going to be in a hurry, worried about money and flawless functionality, and less technical than me, and therefore need managing, and may even force me to compromise in ways I find annoying (or worse). I just mess around in my ivory tower, having coding fun in my favourite language (Jython), with the leisure to spend weeks, for example, on the "philosophy" of exception-handling in Jython. – mike rodent Aug 25 '15 at 19:59
  • I love this answer. Finally one that hits the nail on the damn head. A functional test can touch more than one unit and can be written from either the user, developer, or combination of both's perspective. A functional test is a blanket term covering anything from integration to end-to-end testing. – ThinkingInBits Sep 03 '16 at 20:12
  • 1
    "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." This is kind of nit-picky, but I would call that an "acceptance test." The functional test would test that entering ZZ on the shipping form forwarded the user to the correct URL or threw particular exception or error. – Bob Ray Apr 12 '19 at 19:20
104

TLDR:

To answer the question: Unit Testing is a subtype of Functional Testing.


There are two big groups: Functional and Non-Functional Testing. The best (non-exhaustive) illustration that I found is this one (source: www.inflectra.com):

enter image description here

(1) Unit Testing: testing of small snippets of code (functions/methods). It may be considered as (white-box) functional testing.

When functions are put together, you create a module = a standalone piece, possibly with a User Interface that can be tested (Module Testing). Once you have at least two separate modules, then you glue them together and then comes:

(2) Integration Testing: when you put two or more pieces of (sub)modules or (sub)systems together and see if they play nicely together.

Then you integrate the 3rd module, then the 4th and 5th in whatever order you or your team see fit, and once all the jigsaw pieces are placed together, comes

(3) System Testing: testing SW as a whole. This is pretty much "Integration testing of all pieces together".

If that's OK, then comes

(4) Acceptance Testing: did we build what the customer asked for actually? Of course, Acceptance Testing should be done throughout the lifecycle, not just at the last stage, where you realise that the customer wanted a sportscar and you built a van.

enter image description here

Andrejs
  • 8,412
  • 4
  • 38
  • 42
  • 2
    I saw many pictures like that in the google, which describe "Unit test" as a kind of "Functional test". But why then other answers here describe absolutely different concept: the "Functional test" is rather end-to-end test and the unit test **is not** a functional test? I confused. There are two different "religions" that define the term "Functional test" differently or what? – Ruslan Stelmachenko Jul 09 '17 at 15:06
  • Answers (even highly upvoted ones) can be wrong too ;) – Andrejs Jul 09 '17 at 18:15
  • 1
    I like the picture, but for System Integration Testing, the puzzle should appear to be "complete", without any more places for other pieces to connect. – Jonathon Reinhart Oct 19 '17 at 22:28
  • 5
    @JonathonReinhart - not necessarily. The open edges can represent easy extensibility of the system with new features, which is especially useful if using an development approach like Agile. – Myles Mar 15 '18 at 13:19
  • From multiple conflicting answers above, obviously `Functional Test` is not a standardized term and has different meaning to different people. – Penghe Geng Jul 17 '18 at 13:51
  • What happens with those methods which say interact with a model to get to the database? Testing those imply an integration test already? In that case, would unit testing make sense only for those methods that have everything they need within the class they belong to (module)? thank you for your great answer! – Fernando Gabrieli Mar 08 '19 at 02:55
  • "Functionality test, Performance/Speed test, User experience test, Compatibility test, Security test" – Yousha Aleayoub Jun 22 '20 at 21:05
13

"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
  • 224,642
  • 43
  • 388
  • 389
  • Well, interesting, but the link you show means something different: functional is about function to carry out through the implementation, i.e. testing from the user point of view, that is a function for the user. – Stefano Scarpanti Aug 16 '19 at 11:42
9

The basic distinction, though, is that functional tests test the application from the outside, from the point of view of the user. Unit tests test the application from the inside, from the point of view of the programmer. Functional tests should help you build an application with the right functionality, and guarantee you never accidentally break it. Unit tests should help you to write code that’s clean and bug free.

Taken from "Python TDD" book by Harry Percival

Humoyun Ahmad
  • 6,560
  • 4
  • 41
  • 49
8

According to ISTQB those two are not comparable. Functional testing is not integration testing.

Unit test is one of tests level and functional testing is type of testing.

Basically:

The function of a system (or component) is 'what it does'. This is typically described in a requirements specification, a functional specification, or in use cases.

while

Component testing, also known as unit, module and program testing, searches for defects in, and verifies the functioning of software (e.g. modules, programs, objects, classes, etc.) that are separately testable.

According to ISTQB component/unit test can be functional or not-functional:

Component testing may include testing of functionality and specific non-functional characteristics such as resource-behavior (e.g. memory leaks), performance or robustness testing, as well as structural testing (e.g. decision coverage).

Quotes from Foundations of software testing - ISTQB certification

Kaedys
  • 7,458
  • 1
  • 26
  • 33
Dominik
  • 83
  • 1
  • 4
  • I agree about too much fluff, but anyway they are the biggest player there and this question was about theory, so I think ISTQB should be good enough. – Dominik Jun 09 '16 at 12:49
6

In Rails, the unit folder is meant to hold tests for your models, the functional folder is meant to hold tests for your controllers, and the integration folder is meant to hold tests that involve any number of controllers interacting. Fixtures are a way of organizing test data; they reside in the fixtures folder. The test_helper.rb file holds the default configuration for your tests. u can visit this.

Community
  • 1
  • 1
3

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
  • 84,976
  • 26
  • 176
  • 250
3

AFAIK, unit testing is NOT functional testing. Let me explain with a small example. You want to test if the login functionality of an email web app is working or not, just as a user would. For that, your functional tests should be like this.

1- existing email, wrong password -> login page should show error "wrong password"!
2- non-existing email, any password -> login page should show error "no such email".
3- existing email, right password -> user should be taken to his inbox page.
4- no @symbol in email, right password -> login page should say "errors in form, please fix them!" 

Should our functional tests check if we can login with invalid inputs ? Eg. Email has no @ symbol, username has more than one dot (only one dot is permitted), .com appears before @ etc. ? Generally, no ! That kind of testing goes into your unit tests.

You can check if invalid inputs are rejected inside unit tests as shown in the tests below.

class LoginInputsValidator
  method validate_inputs_values(email, password)
    1-If email is not like string.string@myapp.com, then throw error.
    2-If email contains abusive words, then throw error.
    3-If password is less than 10 chars, throw error.

Notice that the functional test 4 is actually doing what unit test 1 is doing. Sometimes, functional tests can repeat some (not all) of the testing done by unit tests, for different reasons. In our example, we use functional test 4 to check if a particular error message appears on entering invalid input. We don't want to test if all bad inputs are rejected or not. That is the job of unit tests.

MasterJoe
  • 1,280
  • 3
  • 17
  • 46
  • 1
    Good point about functional testing often having a much narrower scope than unit testing (in terms of functional testing being more focussed on essentially proving the expected function is achieved), but I'd say that they kind of describe different dimensions (_composition_ in unit tests vs _purpose_ in functional tests); some unit tests are functional tests, and some functional tests are unit tests, but there's also a lot of the Venn that doesn't overlap. – Myles Mar 15 '18 at 18:35
  • Good examples of what is and isn't in scope for functional tests. – Myles Mar 15 '18 at 18:37
3

very simply we can say:

  • black box: user interface test like functional test
  • white box: code test like unit test

read more here.

Monsieur Aliréza
  • 1,570
  • 2
  • 19
  • 26
2

UNIT TESTING

Unit testing includes testing of smallest unit of code which usually are functions or methods. Unit testing is mostly done by developer of unit/method/function, because they understand the core of a function. The main goal of the developer is to cover code by unit tests.

It has a limitation that some functions cannot be tested through unit tests. Even after the successful completion of all the unit tests; it does not guarantee correct operation of the product. The same function can be used in few parts of the system while the unit test was written only for one usage.

FUNCTIONAL TESTING

It is a type of Black Box testing where testing will be done on the functional aspects of a product without looking into the code. Functional testing is mostly done by a dedicated Software tester. It will include positive, negative and BVA techniques using un standardized data for testing the specified functionality of product. Test coverage is conducted in an improved manner by functional tests than by unit tests. It uses application GUI for testing, so it’s easier to determine what exactly a specific part of the interface is responsible for rather to determine what a code is function responsible for.

1

Unit Test:- Unit testing is particularly used to test the product component by component specially while the product is under development. Junit and Nunit type of tools will also help you to test the product as per the Unit. **Rather than solving the issues after the Integration it is always comfortable to get it resolved early in the development.

Functional Testing:- As for as the Testing is concerned there are two main types of Testing as 1.Functional Test 2.Non-Functional Test.

Non-Functional Test is a test where a Tester will test that The product will perform all those quality attributes that customer doesn't mention but those quality attributes should be there. Like:-Performance,Usability,Security,Load,Stress etc. but in the Functional Test:- The customer is already present with his requirements and those are properly documented,The testers task is to Cross check that whether the Application Functionality is performing according to the Proposed System or not. For that purpose Tester should test for the Implemented functionality with the proposed System.

mohit sarsar
  • 169
  • 3
  • 8
0

Unit testing is usually done by developers. The objective of doing the same is to make sure their code works properly. General rule of thumb is to cover all the paths in code using unit testing.

Functional Testing: This is a good reference. Functional Testing Explanation

  • 7
    Please paste the most important text to your answer, you never know when the page might get removed making the link invalid. – Andrejs Jun 10 '16 at 08:34
0

Test types

  • Unit testing - In Procedural programming unit is a procedure, in Object oriented programming unit is a class. Unit is isolated and reflects a developer perspective
  • Functional testing - more than Unit. User perspective, which describes a feature, use case, story...
    • Integration testing - check if all separately developed components work together. It can be other application, service, library, database, network etc.
      • Narrow integration test - double[About] is used. The main purpose is to check if component is configured in a right way
      • Broad integration test (End to End test, System test) - live version. The main purpose is to check if all components are configured in a right way
    • UI testing - checks if user input triggers a correct action and the UI is changed when some actions are happened
    • ...
  • Non functional testing - other cases
    • Performance testing - calculate a speed and other metrics
    • Usability testing - UX
    • ...

[iOS tests]
[Android tests]

yoAlex5
  • 13,571
  • 5
  • 105
  • 98
0

Unit Tests are written from a programmers or developers 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.

Md. Jamil Ahsan
  • 191
  • 1
  • 6