Functional testing on the Force.com platform

Functional testing on the Force.com platform

Background...

After spending many years developing tests and automation for complex products. Implementing framework after framework in many programming languages for debugging, instrumenting and capturing quality data. I guess it becomes second nature  to consider testing, before even writing the first line of code.

That same thing held true as well, when i started working at writing custom Apex and Visual force code, and even more recently with Lightning, which is close to many other web component development frameworks and also requires some form of testing framework.

In my mind, considering how we could test something and how to setup the prerequisites and test fixtures to accomplish this, was the most important piece. And I, for one, believe it also helps improve the overall design of any application or component, since it forces you to focus on a good separation of concerns, and on smaller components, with a more engineered approach to software development.

As for many of  you, who came to the platform from other languages, it was initially about understanding the syntax and available methods and infrastructure to provide proper testing. From there, realizing that in many cases, proper testing and test cases are even better than documentation and can also be leveraged and used by business users, to align the design with the specifications and functionality of the final application.

Reviewing other people's code over the years, i have also found that there are three main approaches that people have, when implementing tests on the platform:

3 Approaches to testing...

The "Just get it done to meet the requirements" approach. Where you just want to do the bare minimum to meet the 75% coverage, many times not even adding any system.asserts(), startTest()/stopTest() methods... And even, at times the use of workaround snippets like the infamous  multi-line  j++.....

The "Aim for 100% line coverage" approach. Where your focus is on covering every line and logical branch to reach that 100% coverage. The downside of this approach is that the focus is not necessarily on the functionality and many times, the corner cases and negative / limit tests are not addressed.

The "What are we trying to test functionality" approach, which, in my mind is what a good test should aim for, with as many test cases as it takes to cover and focus on the negative, positive, and limits functionality. Basically, implementing the business requirements into test cases.  When done right, using this approach, you will always reach the 100% coverage, and provide a platform for your tests to be usable as a live documentation, as well as for business test cases and validation over time.

5 Key elements of good Apex testing...

Based on the approaches above, here are the key elements of good apex testing (note that officially there are many more, but the below are the bare minimum that everyone should aim for when approaching "functional" testing, and that i found cover most of the functionality in a majority of cases):

  • Use of @TestSetup, @TestVisible decorators to properly and effectively setup your test fixtures, and control the behavior of your test cases.
  • System.RunAs() method to identify profile specific behavior and test contexts.
  • Test.startTest() / Test.stopTest() and limit methods in order to consolidate your test cases within an execution context, helping to identify limit issues.
  • Lots of System.assert() methods, to actually confirm that your test cases are validating the functionality of the application.
  • Negative, Positive, Limit and Bulk Test cases, need i say more? Good test cases, should validate for negative and limit testing, as well as positive...
  • Inline test code documentation and assumptions, so that someone reading your code to understand or debug how a particular feature or piece of functionality, is able to understand and navigate your logic.

Other testing considerations...

As i mentioned, the above list is not exhaustive, and depending on your test cases, you might need to consider mocks, test data factories, test.LoadData, (seeAllData=true) and test.isRunningTest() conditions, but focusing on the above 5 key elements will help you to implement good apex testing.

Final words about functional testing...

Over the years, i have found that you can, and should use tests, even to validate business cases that are not necessarily directly related to pieces of code.

An example of this, would be a complicated business process that involves approvals, at many levels, and with branches based on different entry criteria and many geographical regions. 

In this case, the business users would take hours and days at times, setting up the right data and validating the process over many geographical regions, not to mention that they needed to review the data in the process, to make sure every scenario was covered !

After replacing this with a one time and ~52 test cases test class, it now takes about 30 minutes to run (a long running test that is not run in production !) but it covers all cases and ensures business that their process is working when making changes of any sort, not to mention that it clearly describes and documents the process by the same token.

I've also realized that, even with the best strategy about test cases, you cannot ensure everything will be bug free ! This is a known fact as illustrated by this quote:

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning..." - Rick Cook

But then following the good apex testing philosophy, means that it is ok and that you should add more tests, and test cases down the line, as soon as bugs are found and expose potentially missing test cases...

Conclusion

Hopefully with this post, you have recognized yourself, into one of those approaches to testing, and learned about the key elements of good apex testing that you can start to explore and use, in your development on a day to day basis.

You have also hopefully learned that you can and should use testing in many forms, even for business cases functional testing. And that you can and should add more tests as bugs are found, to help keep your processes and org healthy !

References:

 About me

Thanks to David Claiborne for his comment on this post, adding a note that, as part of negative / limit-testing, an important consideration is test cases that consider "null" values (aka: fields that do not have values). This is an important piece of the negative / limit test case testing... Happy testing ! Feel free to share your comments, questions

To view or add a comment, sign in

Others also viewed

Explore content categories