In my (I admit) little experience, I understood that the word integration can really create misunderstandings: really, it's difficult to find something completely isolated in a system, some elements will need some integration for sure.
Thus, I got accustomed to make the following distinctions:
- I use unit test to identify,
document and stress all the behaviors
the class I'm testing is responsible
to accomplish.
- I'm doing integration tests
whenever I have a component (maybe
more than one) in my system which is
having some conversation with another
"external" system. (continues
below...)
- I implement an acceptance test to define,
document and stress a certain
workflow which is expected by the
system.
In the integration test definition, by external I meant system which are out of my development range: I cannot change immediately the way they behave, for any reason. It could be a library, a component of the system which cannot be changed (i.e. it is shared with other projects in the company), a dbms, etc. For these tests I need to set up something very similar to the real environment the system will work in: an external system must be initialized and set to a certain state; realistic data must be registered in the db; etc.
Instead, when I'm doing acceptance testing I fake things: I'm working on something different, I'm working on the specifications of the system, not on it's ability to collaborate with external entities.
This really is a narrower view compared to what KeesDijk described earlier, however I suppose the projects I worked on till now were small enough to let me this level of simplification.