Real project showed to me that it's not possible to write unit tests and than integration and even opposite direction is wrong :-) So, I usualy write unit tests together with integration ones.
Why? Let me to write how I see both kinds of tests:
Unit tests - In addition to wikipedia and all know information, unit tests help you to narrow your design, improve your model, relations. The flow is simple: once you start to type new project/new component, most of time you are making some kind of PoC. When you are done, you always have long methods, long classes, non-coherent methods and classes, etc.
Unit tests help you to remove these issues as when you do real unit testing using mocks (w/o dependency on other component) classes described above are un-testable. Basic sign of untestable code is large mocking part of tests because you are forced to mock many dependencies (or situations)
Integration tests - correct and working tests say to you that your new component (or components) work together or with other components - this is usual definition. I've found that integration tests mostly help you to define flow how to use your component from consumer side.
This is really important as it sometimes says to you that your API does not make sense from outside.
Well, what happen once I wrote unit tests and integration tests later?
I got nice classes, clear design, good constructor, short and coherent methods, IoC ready etc. Once I give my class/API to some consumer, e.g. developer from integration or GUI team, he was unable to use my API as it seems unlogic, weird. He was just confused. So I repaired API according to his point of view but it also required to rewrite many tests because I was pushed to change methods and sometimes even the flow how to use the API.
Well, what happen once I wrote integration tests and unit tests later?
I got exact flow, good usability. What I also have are large classes, non-coherent code, no logging, long methods. Spaghetti code
What's my advice?
I've learned following flow:
- Develop basic skeleton of your code
- Write integration tests which say whether it make sense from consumer point of view. Basic use-case is enough for now. The test obviously does not work.
- Write code along with unit tests for each class.
- Write the rest/missing of integration tests. It would be better to implement these test within #3 how you are improving your code.
Note that I've made small presentation about unit/integration testing, see slide #21 where the skeleton is described.