views:

2072

answers:

12

I know the so-called textbook definition of unit tests and integration tests. What I am curious about is when it is time to write unit tests... I will write them to cover as many sets of classes as possible.

For example, if I have a Word class, I will write some unit tests for the Word class. Then, I begin writing my Sentence class, and when it needs to interact with the Word class, I will often write my unit tests such that they test both Sentence and Word... at least in the places where they interact.

Have these tests essentially become integration tests because they now test the integration of these 2 classes? Or is it just a unit test that spans 2 classes?

In general, because of this uncertain line, I will rarely actually write integration tests... or is my using the finished product to see if all the pieces work properly the actual integration tests, even though they are manual and rarely repeated beyond the scope of each individual feature?

Am I misunderstanding integration tests, or is there really just very little difference between integration and unit tests?

EDIT: Thanks for all the great responses everyone! I think from the varied answers it's clear that the line between unit and integration tests is definitely a blurry line, and perhaps it's a bit pedantic to try and figure out which are which and the true focus should stay on the code (Thanks @Rob Cooper). Also, sorry but I'm not going to accept any answer because too many are too good, and it really seems quite subjective.

+5  A: 

using Single responsibility design, its black and white. More than 1 responsibility, its an integration test.

By the duck test (looks, quacks, waddles, its a duck), its just a unit test with more than 1 newed object in it.

When you get into mvc and testing it, controller tests are always integration, because the controller contains both a model unit and a view unit. Testing logic in that model, I would call a unit test.

DevelopingChris
+7  A: 

I think when you start thinking about integration tests, you are speaking more of a cross between physical layers rather than logical layers.

For example, if your tests concern itself with generating content, it's a unit test: if your test concerns itself with just writing to disk, it's still a unit test, but once you test for both I/O AND the content of the file, then you have yourself an integration test. When you test the output of a function within a service, it's a unit-test, but once you make a service call and see if the function result is the same, then that's an integration test.

Technically you cannot unit test just-one-class anyway. What if your class is composed with several other classes? Does that automatically make it an integration test? I don't think so.

Jon Limjap
"Technically you cannot unit test just-one-class anyway. What if your class is composed with several other classes?" Well, a "strict" unit test would just mock/stub all the dependencies. However, it is debatable whether this is always practical...
sleske
That's true sieske -- the important bit is to be able to keep dependencies to an absolute minimum.
Jon Limjap
+1  A: 

Unit testing is testing against a unit of work or a block of code if you like. Usually performed by a single developer.

Integration testing refers to the test that is performed, preferably on an integration server, when a developer commits their code to a source control repository. Integration testing might be performed by utilities such as Cruise Control.

So you do your unit testing to validate that the unit of work you have built is working and then the integration test validates that whatever you have added to the repository didn't break something else.

Christian Hagelid
+1  A: 

I think I would still call a couple of interacting classes a unit test provided that the unit tests for class1 are testing class1's features, and the unit tests for class2 are testing its features, and also that they are not hitting the database.

I call a test an integration test when it runs through most of my stack and even hits the database.

I really like this question, because TDD discussion sometimes feels a bit too purist to me, and it's good for me to see some concrete examples.

Lance Fisher
A: 

A little bit academic this question, isn't it? ;-) My point of view: For me an integration test is the test of the whole part, not if two parts out of ten are going together. Our integration test shows, if the master build (containing 40 projects) will succeed. For the projects we have tons of unit tests. The most important thing concerning unit tests for me is, that one unit test must not be dependent on another unit test. So for me both test you describe above are unit tests, if they are independent. For integration tests this need not to be important.

John Smithers
+2  A: 

I do the same - I call them all unit tests, but at some point I have a "unit test" that covers so much I often rename it to "..IntegrationTest" - just a name change only, nothing else changes.

I think there is a continuation from "atomic tests" (testing one tiny class, or a method) to unit tests (class level) and integration tests - and then functional test (which are normally covering a lot more stuff from the top down) - there doesn't seem to be a clean cut off.

If your test sets up data, and perhaps loads a database/file etc, then perhaps its more of an integration test (integration tests I find use less mocks and more real classes, but that doesn't mean you can't mock out some of the system).

Michael Neale
+4  A: 

My 10 bits :D

I was always told that Unit Tests is the testing of an individual component - which should be exercised to its fullest. Now, this tends to have many levels, since most components are made of smaller parts. For me, a unit is a functional part of the system. So it has to provide something of value (i.e. not a method for string parsing, but a HtmlSanitizer perhaps).

Integration Tests is the next step up, its taking one or more components and making sure they work together as they should.. You are then above the intricacies of worry about how the components work individually, but when you enter html into your HtmlEditControl , it somehow magically knows wether its valid or not..

Its a real movable line though.. I'd rather focus more on getting the damn code to work full stop ^_^

Rob Cooper
A: 

Unit Testing is a method of testing that verifies the individual units of source code are working properly.

Integration Testing is the phase of software testing in which individual software modules are combined and tested as a group.

Wikipedia defines a unit as the smallest testable part of an application, which in Java/C# is a method. But in your example of Word and Sentence class I would probably just write the tests for sentence since I would likely find it overkill to use a mock word class in order to test the sentence class. So sentence would be my unit and word is an implementation detail of that unit.

grom
A: 

I call unit tests those tests that white box test a class. Any dependencies that class requires is replaced with fake ones (mocks).

Integration tests are those tests where multiple classes and their interactions are tested at the same time. Only some dependencies in these cases are faked/mocked.

I wouldn't call Controller's integration tests unless one of their dependencies is a real one (i.e. not faked) (e.g. IFormsAuthentication).

Separating the two types of tests is useful for testing the system at different levels. Also, integration tests tend to be long lived, and unit tests are supposed to be quick. The execution speed distinction means they're executed differently. In our dev processes, unit tests are run at check-in (which is fine cos they're super quick), and integration tests are run once/twice per day. I try and run integration tests as often as possible, but usually hitting the database/writing to files/making rpc's/etc slows.

That raises another important point, unit tests should avoid hitting IO (e.g. disk, network, db). Otherwise they slow down alot. It takes a bit of effort to design these IO dependencies out - i can't admit I've been faithful to the "unit tests must be fast" rule, but if you are, the benefits on a much larger system become apparent very quickly.

CVertex
+7  A: 

When I write unit tests I limit the scope of the code being tested to the class I am currently writing by mocking dependencies. If I am writing a Sentence class, and Sentence has a dependency on Word, I will use a mock Word. By mocking Word I can focus only on its interface and test the various behaviors of my Sentence class as it interacts with Word's interface. This way I am only testing the behavior and implementation of Sentence and not at the same time testing the implentation of Word.

Once I've written the unit tests to ensure Sentence behaves correctly when it ineteracts with Word based on Word's interface I write the integration test to make sure that my assumptions about the interactions where correct. For this I supply the actual objects and write a test that excercises a feature that will end up using both Sentence and Word.

lfoulkrod
A: 

Have these tests essentially become integration tests because they now test the integration of these 2 classes? Or is it just a unit test that spans 2 classes?

I think Yes and Yes. Your unit test that spans 2 classes became an integration test.

You could avoid it by testing Sentence class with mock implementation - MockWord class, which is important when those parts of system are large enough to be implemented by different developers. In that case Word is unit tested alone, Sentence is unit tested with help of MockWord, and then Sentence is integration-tested with Word.

Exaple of real difference can be following 1) Array of 1,000,000 elements is easily unit tested and works fine. 2) BubbleSort is easily unit tested on mock array of 10 elements and also works fine 3) Integration testing shows that something is not so fine.

If these parts are developed by single person, most likely problem will be found while unit testing BubbleSoft just because developer already has real array and he does not need mock implementation.

Pavel Feldman
+3  A: 

Unit tests use mocks

The thing you're talking about are integration tests that actually test the whole integration of your system. But when you do unit testing you should actually test each unit separatelly. Everything else sould be mocked. So in your case of Sentence class, if it uses Word class, then your Word class should be mocked. This way, you'll only test your Sentence class.

Robert Koritnik