We here in Internal Systems have started work on a fairly typical-for-us project: we’re rewriting the application that sends data from our ordering system (HAMS) to our financial system (Netsuite).
FISC, the new application, will provide a REST-based interface which HAMS will call upon invoice payment. It’s not a technically difficult or even a large application, but because it deals with financial information it’s very, very important to get right.
Developing our New Application
We didn’t quite embrace test-driven development as we wrote FISC, but we did keep asking ourselves, “how can we unit test this?”. This is a bit of a departure from our typical development process which is where we ask ourselves, “how are we going to implement this?”. We’re using dependency injection and interfaces to make mocking out of services easy. We’ve made sure that each bit of code does one thing well rather than trying to do everything at once. In one case we split up one class into four, just to make it easier to test. It may sound like overkill but it’s meant that we’ve ended up with very modular code.
Embracing Code Coverage
Exclusions for Fun and Profit
We want to make sure that we were focusing on covering the right code – rather than focusing on covering all code. I always exclude private methods and property methods, because I know we’re not interested in covering them:
I also used Clover’s exclusion feature to exclude all the automatically generated Netsuite code. This menu option is new in Clover 2.6 and has saved me umpteen units of effort trying to remember how to format Ant style patternsets:
We’ve been able to achieve 100% code coverage for the vast majority of the application. We’re not aiming for 100% for completeness’ sake, but to help us sleep at night! There’s a lot of business logic, with a lot of different branches, and a lot of pain if we get this wrong. The Clover Cloud Report helped us identify which classes we needed to prioritise testing for. It managed to find the class with the scariest business logic fairly easily:
By far the most helpful function I’ve found with Clover is the new “Hide elements with full coverage” option in the Coverage pane:
We’ve been using this view as a quick way to identify which methods require unit testing. It’s helped us pick up branches that we thought we’d covered but hadn’t, and helps us ignore the classes we’re already covering. It’s also been pretty satisfying to see the list of methods in the pane get smaller and smaller.
Sleeping Well at Night
Unit testing is the key to the successful deployment of FISC – we won’t begin integration testing until we are happy with our unit test coverage. And Clover has become integral to our unit testing effort, because it’s the tool that’s let us know what we’ve tested. Sure, it’s still up to us to make sure the right values go in and the right values come out but that’s a lot less stressful than lying awake wondering whether you’ve covered the case where an Australian partner paying in USD with an AMEX for a new two year Confluence license with three additional nodes.
Tips for young players: Some of the Clover features we used are new in Clover 2.6, which is scheduled for release in early September