Best Practice: When to Use Public Test Classes

Since the APIv23.0 release (aka Winter 12) it’s been possible to have a non-private class annotated @isTest. You might first wonder why this would ever be useful.

If you aren’t using some sort of mocking framework, or even if you are, there’s a quite good chance that you’ll have common logic in your test methods. Chances are this logic is for things like mundane data setup that’s never going to be used outside of a test context. The big win from this feature is that you can make non-test public methods inside @isTest classes.

My favorite feature of doing so is compile-time validation that your method is only being used inside tests; referencing a isTest class’ public methods from a non-test context fails to execute them by throwing a (catchable) TypeException. Beyond that any methods defined this way don’t count as code that needs it’s own test coverage, so you don’t have to have a (hypothetically named) TestUtilsTest class to go with your TestUtils.

Even more interesting to the ISVs among us is that isTest classes their contained methods can be global. This means that as a package author you can potentially expose test-only methods to do things that would otherwise be forbidden, like disabling triggers or creating a predefined set of baseline data that customers might not be able to initialize.

In the grand scheme of things it’s hardly more than a neat little trick, but these neat little tricks add up over time and end up making all the difference in the world.