Getting to the root of a problem…
So someone raised a great point about my last post, noticing that it is usually hard to pinpoint the exact line of code where your error is when a test fails. Usually, you know which line in the test failed, but not why. That happens when you have integration tests, and not unit tests.
When I say “Pin point breakages and causes of failures to the line level”, I actually do mean that. It is quite possible to do this with true unit tests. This comes back to the definition of a unit test. It should be testing one unit or method, and not testing things across classes. So if you want to isolate the cause of the breakage, we mock out anything that is not this class to truly test just this class.
Consider this example, you have a class House which has a few methods like enterHouse() and lockHouseAndLeave(). A house has some members like door, rooms, etc. When we test enterHouse(), we mock out the door and rooms, and assume those work perfectly (Since we test those individually as well for correctness). We then test just enterHouse(), and have the mocks return what we expect it should in the correct behavior. That way, if anything breaks in a test for enterHouse(), you cna be totally assured it is something because of enterHouse(), and rarely have to dig in deep.
Now if you have an integration test, where you don’t have mocks for Doors and rooms, you are going to have trouble pinpointing the point of breakage, but with mocks, and proper unit testing, you know exactly what is being tested and what is causing the test to fail.
Though getting to this point where you can test pieces in isolation either requires you start designing with testability in mind or refactoring stuff to get it where you can inject mocks.
In my next post, I plan to talk about code coverage, one of the easiest ways to figure out what is untested and some caveats.