397

What's the difference between unit tests and integration tests?

Are there different names for these tests? Like some people calling unit tests functional tests, etc?

nbro
  • 12,226
  • 19
  • 85
  • 163
Books
  • 4,773
  • 5
  • 17
  • 16

5 Answers5

628

A unit test is a test written by the programmer to verify that a relatively small piece of code is doing what it is intended to do. They are narrow in scope, they should be easy to write and execute, and their effectiveness depends on what the programmer considers to be useful. The tests are intended for the use of the programmer, they are not directly useful to anybody else, though, if they do their job, testers and users downstream should benefit from seeing fewer bugs.

Part of being a unit test is the implication that things outside the code under test are mocked or stubbed out. Unit tests shouldn't have dependencies on outside systems. They test internal consistency as opposed to proving that they play nicely with some outside system.

An integration test is done to demonstrate that different pieces of the system work together. Integration tests can cover whole applications, and they require much more effort to put together. They usually require resources like database instances and hardware to be allocated for them. The integration tests do a more convincing job of demonstrating the system works (especially to non-programmers) than a set of unit tests can, at least to the extent the integration test environment resembles production.

Actually "integration test" gets used for a wide variety of things, from full-on system tests against an environment made to resemble production to any test that uses a resource (like a database or queue) that isn't mocked out. At the lower end of the spectrum an integration test could be a junit test where a repository is exercised against an in-memory database, toward the upper end it could be a system test verifying applications can exchange messages.

Nathan Hughes
  • 85,411
  • 19
  • 161
  • 250
  • 24
    The description of unit testing is very good but have you considered that pairwise integration does not cover whole applications just two testable units and that system testing also covers whole applications. – Dave Jan 06 '13 at 21:00
  • 20
    The difference is not about the size of the tested code. This definition also missed a practical aspect: unit tests should only depend on the tested implementation unit; they should not depend on external components such as databases, network services, web browser interaction. When such external elements are required, unit tests use mock objects. – Paulo Merson May 18 '14 at 12:30
  • 1
    @Paulo: agreed, I added a section to cover that. If you would like to suggest an edit I'll be happy to approve it. – Nathan Hughes May 20 '14 at 14:14
  • 17
    It took me ages to understand this because when you say unit, I used to think an example of "small chunk of code" was getCitiesFromCountry(string Country) should verify that the database returns "London, Manchester" if you pass in "UK". That to me was a unit. So I'd use a mock to mock the database and try to return a filtered list. I now understand that as being an integration test and something that will be picked up by QAs if the database returns New York when asked for cities in the UK. The unit test just tests that the round trip e.g. to the controller was called and behaved as it should. – Developer1010 Oct 01 '15 at 10:37
  • 2
    @PauloMerson That is a very good point, thanks. Size of the tested code does not define a unit. I actually have been told otherwise by senior devs who would tolerate external database connections in their unit tests, which proves that the subject is very confusing. – Piotr Kusmierczyk Aug 23 '17 at 20:25
  • 5
    I would add that currently (in mid-2018 as I write this) integration tests are far cheaper to perform than they once were. This is largely due to the continued movement towards containerization. If you need a database, redis, SFTP, etc., they are literally a "docker pull" away, and docker-compose makes it very easy to bring up your application with its dependencies in a single "docker-compose up" command. – Josh Jul 11 '18 at 15:28
  • This article was really helpful in understanding the difference between Unit Tests, Integration Tests and Functional Tests with comparisons between each. https://www.softwaretestinghelp.com/the-difference-between-unit-integration-and-functional-testing/ – w00ngy Oct 02 '20 at 13:21
105

A unit test should have no dependencies on code outside the unit tested. You decide what the unit is by looking for the smallest testable part. Where there are dependencies they should be replaced by false objects. Mocks, stubs .. The tests execution thread starts and ends within the smallest testable unit.

When false objects are replaced by real objects and tests execution thread crosses into other testable units, you have an integration test

Abdullah Khan
  • 9,469
  • 3
  • 52
  • 64
Dave
  • 3,544
  • 6
  • 36
  • 43
  • 2
    thanks @Dave but why should a unit test have no external dependencies? – BKSpurgeon Dec 06 '16 at 00:25
  • 11
    @BKSpurgeon because in a unit test you only want to check the behavior of the tested function in a well-defined context. It should not be influenced by a potential bug in the dependencies. If you want to assert that the combination of the function and the dependencies works as expected, you are writing a integration test. – Emarco Dec 07 '16 at 10:19
  • 3
    In my experience (often banking, often bad code on a grand scale), everyone calls all testing "unit tests". They also tend to rush and code methods into effectively big long scripts and not design properly so they can't do true unit testing, but they think they are unit tests because they made them run fine without a network connection. When you compose your designs of hundreds of tiny, laser-focused classes and frameworkify stuff into NuGet packages, then what unit-testing really is becomes obvious. – Luke Puplett Nov 15 '17 at 10:26
45

A unit test is done in (as far as possible) total isolation.

An integration test is done when the tested object or module is working like it should be, with other bits of code.

The Communist Duck
  • 5,649
  • 3
  • 33
  • 47
18

A unit test tests code that you have complete control over whereas an integration test tests how your code uses or "integrates" with some other code.

So you would write unit tests to make sure your own libraries work as intended, and then write integration tests to make sure your code plays nicely with other code you are making use of, for instance a library.

Functional tests are related to integration tests, but refer more specifically to tests that test an entire system or application with all of the code running together, almost a super integration test.

Karl Rosaen
  • 4,050
  • 1
  • 25
  • 29
  • 4
    also worth mentioning that unit tests typically refer to tests that test a minimal amount of code, for example a single function – Karl Rosaen Mar 18 '11 at 20:45
13

Unit test is usually done for a single functionality implemented in Software module. The scope of testing is entirely within this SW module. Unit test never fulfils the final functional requirements. It comes under whitebox testing methodology..

Whereas Integration test is done to ensure the different SW module implementations. Testing is usually carried out after module level integration is done in SW development.. This test will cover the functional requirements but not enough to ensure system validation.

BenMorel
  • 30,280
  • 40
  • 163
  • 285
Jeganraj
  • 353
  • 2
  • 4
  • 9