June 7, 2013

SmartFactory: Easier Salesforce Test Methods

Some weeks ago I wrote a post about the importance of writing good test methods when developing on force.com, and I want to follow up on that just to labour the point some more. Test methods can so often seem like a chore, especially when you refactor some code and need to change them because they fail, but good tests are imperative, for your own peace of mind as much as anything else.

Tests Are Important

Just today I was adding some functionality to a work in progress, and at some point seemingly broke a test; just before I started editing the test method itself, I realised that the test was performing a sequence of tasks that a user was likely to perform also. The fact that the test was failing meant that I had an issue to resolve in the code itself, not, as I initially thought, the test. Because that test started failing I was able to improve the application being built, and I as such, I was lucky.

Tests Are Tedious

Just because I'm promoting the proper usage of test methods, I'm not saying that I find them a joy to write. As all good force.com developers know, you should not rely on existing system data for your tests to work with, but inserting records into a foreign org which could have any number of unexpected validation rules and required fields makes for a lot of extra code, or a high risk of test failure. There are many ways to include data for tests, including through static resources, but every method has its own peculiarities.

Getting Smart With Test Data

For the application I'm building at the moment, I've started using a publicly available Apex library called SmartFactory from Force.com MVP, Matthew Botos (@BotosCloud. While I've been aware of this code for a while now (it's been around since 2011) I never managed to actually look at it in detail, though that's largely because of the usual developer bent: "I'll do it the way I know for now, even if it is slow, because learning that might take me longer". If you're anything like me you'll perform a repetitive task a multitude of times before realising you're wasting time, and it's a trait I'm working hard at eradicating.

For the tests I am working with at present, SmartFactory has been a huge time saver, implementing it took no time at all and allowed me to replace tens of lines of object creation with a mere handful. The following snippet quoted straight from the README.md file should be more than enough to whet your appetite.

Just use SmartFactory in your tests to create objects:

Account account = (Account)SmartFactory.createSObject('Account');

To cascade and create lookup objects:

Contact contact = (Contact)SmartFactory.createSObject('Contact', true);

It really is that simple, so why not start using it right now? Remember, properly written tests are your friend. If you simply aim for code coverage then tests will always be a chore, and coverage is a dubious (albeit required) metric for quality if at all. Tests which make use of System.Assert() and actually validate functionality are far more beneficial, and the effort to write them is barely any greater than that needed for basic coverage. If you write proper tests you will be helping yourself, your QA team, and ultimately, your users, so there is no good excuse not to. Write good tests: because awesome.