Microsoft’s guidance for unit testing actually describes integration testing – level 200
I commend Microsoft for putting a big emphasis on automated testing. This is a big step for the software industry as a whole to embrace automated testing. The hardware industry has already discovered this and has a built-in self-test in almost every device. Likewise, software should have built-in self-tests to ensure that everything is working.
Microsoft has provided Unit Testing and Generating Source Code for Unit Test Frameworks Using Visual Studio 2005 Team System. In this article they describe how to unit test some code using Team System’s automated testing features. The problem is that what is actually described is integration testing. The tests call a BankAccount object and exercise some methods. There is no mocking(stubbing) of BankAccount’s dependencies, so this cannot be a unit test. If BankAccount actually works, it will have to communicate with some dependency unless this BankAccount keeps everything in memory.
Here are some recommended “unit tests” from the article:
Clearly, the assumption is made that a database is in the testing stack. This disqualifies the tests from being unit tests because they include a dependency and test more code than the “unit” – BankAccount component.
Automated testing is very important, but I must clarify some points in this article. The testing described here is “integration testing”. This kind of testing is important too, but it’s important to make the distinction. Unit tests test at the unit level and exclude a database. Unit tests are fast and can run on any workstation, not just a specially configured development environment.
Integration tests include multiple components of a system and make sure the pieces work together. In an integration test, it is appropriate to include multiple components including a database. For unit testing, including a database is not appropriate.
While I understand what you are saying and I completely agree, I think it would be helpful to elaborate on the practical differences…
For example, Microsoft suggests I do a Constructor test on my bank account object. That seems logical. So do I need a unit test that validates the behavior of the object’s constructor using a mock object and then an integration test on the constructor that uses a development database? Would these tests be pretty much identical?
It seems like there should be an article somewhere that says, for each object you will probably need to test “x” with your unit tests and “y” with your integration tests, but I have never seen an article like that.
Thanks for your informative blog, btw.
Cody
First, you don’t want to put much logic in a constructor. I normally only use the constructor to receive arguments and assign them to fields. These arguments are normally the object dependencies, and my parameterless constructor grabs my default dependencies.
Unit tests and integration tests may be similar-looking, and that’s perfectly reasonable. The unit test ensures that the class does what it is supposed to do. The integration test encompases the scope of the unit tests but also would test the assumptions made in what is needed to communicate all the way to the database. Even though the test code may look similar, it’s important to run both because they test different things.