Salesforce makes it simple to quickly create useful solutions for your business. “Modify your database schema – no DBA required!” “Clicks – not code!” “Become an Apex developer in 24 hours!” But too often, there is a lack of attention on other important heuristics such as scalability, maintainability, usability, quality, etc. This article addresses just a few important things to consider while developing your high-quality Salesforce solution.
Data integrity is mandatory for the success of your solution. If information is not reliable and consistent, users won’t use the product. There are two keys to ensuring the integrity of your data:
Don’t duplicate information. If a field needs to be accessible from multiple objects, use formulas or workflow rules to keep the data reliably synchronized. As a last resort, develop a trigger.
Define fields as restrictively as possible. For example, if you need to store a web site address, use URL instead of Text for the field type. Use Phone Number or Currency instead of Number. If a field should never have a value larger than 999, set the field length to 3.
When possible, check those “required” and “unique” boxes. Define filters and validation rules generously. Add help text to fields so that users understand what’s being asked of them. All these steps will assist your users in entering valid data.
Finally, when data integrity defects arise, resist the urge to simply blame “invalid values” or “bad data”. If a value exists in Salesforce, it’s because you allowed it to be stored. Avoid duplication and be restrictive to avoid creating data integrity problems.
Once your data integrity measures are in place, you’ll still need to consider how your application will respond when the user makes a mistake. By following the suggestions above for data integrity, you’ll be well on your way toward preventing and handling user errors. Due to a restrictive schema, users will be notified if they’ve missed a required field, entered an invalid phone number, or added a duplicate Widget. Besides user errors, you’ll have other things go wrong now and then that will also need to be handled appropriately. Let’s group these into two broad categories – code defects and system errors.
This type of error is introduced in the development process and therefore, ideally, should be caught and resolved there as well – before your application gets to end users. Developers should use assertions (System.assert*) freely in order to detect invalid inputs, logic errors, and general misuse of their code. Unit tests are another excellent way to find code defects early. In order for unit tests to be effective, they must test positive and negative cases, test bulk operations, and assert correctness.
System errors include all issues that rely on data, Salesforce server reliability, and external dependencies. These errors are neglected because they happen infrequently or sometime after the initial development. Even though it rarely happens, every Apex DML statement has the possibility of failing. Despite the fact that your integration to a web service works flawlessly today, a callout may fail or return invalid information next month. These potential errors need to be identified, tested for if possible, and handled appropriately. Developers should be very familiar with exception handling, database savepoints, and HTML status codes.
I’m a huge fan of testing. In my experience, one of the best ways to find and prevent defects is through thorough testing. And thorough testing is very tedious unless automated.
Luckily, Salesforce enforces and automates the execution of unit tests when deploying to production. Once you’ve written your unit tests, Salesforce will automatically execute them during each deployment. Unluckily, there’s no easy way to enforce effective unit tests. Code coverage is not enough. Since you must write unit tests, use the time wisely and create tests that validate the correctness and efficiency of your code.
Adding effective unit tests is easiest if done before or during code development. By the end of the process, deadlines are looming or past, the developer is eager to move on to the next challenge, and the energy required to produce really good unit tests is lacking. So instead of adding code coverage tests as an afterthought, get familiar with Test-Driven Development, or at least add good unit tests as you complete each method you write. Writing tests up front has the added bonus of forcing you to design for effective testing. You’ll soon find that you’re writing small, single-purpose methods that can be easily and completely tested.
Consider devoting a portion of your user-testing to security issues. Salesforce itself is very security-aware, but if your solution includes custom VisualForce or Apex code, you’ll need to be mindful of the possible security dangers. Developers should be wary of user input. Macros and library functions are available for encoding and decoding user input to prevent cross-site scripting. Sensitive data can be protected using built-in encryption/decryption utilities. Classes should be declared “with sharing” when possible to enforce configured sharing settings. Finally, an excellent source of Apex security utilities is the ESAPI security library.
Salesforce is an exciting “rapid-development” platform for your business needs. To improve the quality of your Salesforce solutions, add processes to ensure data integrity, good error handling, testing, and security.