Three levels of apex testing

By

6 minutes de lecture

Salesforce gives some powerful tools to test an org’s apex code. Which comes with a great responsibility: get to at least 75% coverage for all apex classes. This forces us to test our code, which is a good thing. But only reaching minimum coverage is not enough. If we want to make sure we are developing a maintainable application. We also like to make sure the code is doing what it is supposed to do.

Coverage testing

The first level is coverage only. This can happen when one is running out of time when designing tests and just wants to achieve 75% coverage in order to deploy into production. This is not recommended as the apex code will not be tested and can present numerous bugs and still pass the tests. It only makes sure that the covered code runs without crashing or raising an exception (in the specific case that was presented), which is not enough to say that the code works well.

This level includes tricks such as artificially increasing the number of lines (by adding useless lines, for instance). In a method in order to get to 75% without testing that much of the code. In general, if the minimum coverage is not reached, this probably means that we should write more tests to cover the remaining pieces of code.

It is also possible to cover the tested methods without actually testing it, by not using any assertion after the call. This also ensures that the methods don’t crash. But does not test the output of the methods. Hence, it does not verify that the code is doing what it is supposed to.

One last piece of advice that may be straightforward for some, it to avoid names like “Test” or “Approval” when writing a class (test or not). These are standard classes in Salesforce. But are not necessarily forbidden names, and you can overload the standard Test class and make all your org tests fail at once.

Unit testing

This level, unlike the previous one, is acceptable in that is really tests the code and not only covers it.

Based on what was said in the previous section, the test methods should always include assertions (assert, assertEquals, etc…). That make the difference between coverage and testing. Different tests should also be splitted into different unit methods, so that it is easier to see which part failed when running it.

Usually, tested classes work on data, and it is always a good idea to create test data before running the method whenever possible (whether it is in a setup method or before calling the tested method). The SeeAllData=true annotation is sometime necessary in specific cases. But it should be avoided when it is possible. It can be useful to have a test data factory. Where you can put many methods creating common test data that you can reuse in your different test methods. This presents the advantage of being easy to maintain since all test data are created in one single place.

Finally, as presented in the Salesforce documentation, there are some guidelines to follow when writing your tests. First, as apex methods should be bulkified whenever it is possible. Apex should be tested in single as well as bulk cases. It is also important to test positive cases (in which the process should work) as well as negative cases (in which the code should raise an exception, for instance, and check that the error message is correct). Testing data access (with different kind of users and different profiles) is also important and can be achieved using the System.RunAs method.

Functional testing

This final stage includes all good practices that make tests at the same time easier to understand and very useful when developing new features. In a word, these include tests that make sense in a functional point of view.

To begin with, it can be useful to use data that are realistic in an end user perspective. This has the advantage that it can be discussed with the users. And also that can better picture the different cases that are presented. It also ensure that, for any reason, the tests do not make errors with these kind of data when it could have worked well when presented simpler data. Here we can see the advantage of using a test data factory class. As a realistic case can be used in many scenarios and improved with time.

After creating some realistic data, you can make the tests methods. So that each one represents a bit of business process that the end user would actually do this way. Again, this ensures that the code is tested with the same logic it will be used. Also, by splitting your tests into functionals bits, you will be able to tell quickly which business process is affected by a modification or a new feature that you just added. Instead of an abstract scenario that will never be used in any way. This logic gets closer to the Test Driven Development logic, where tests are written before the development (the business needs drive the tests, that drive the development). However, this kind of test takes more time to make and also require a stronger collaboration with end users than the other kind of tests.

Conclusion

Testing your apex is not only a requirement of Salesforce. It is also important to make sure the code does what it is intended to, and nothing else. It is also an important maintenance tool when adding new features or changing old ones.

Practices that only increase code coverage without actually testing it are strongly advised against. And there is a list of good practices that can be found in the testing examples in the Salesforce documentation.

These are only a few leads to think about the way we do apex testing in our projects. Some practices are to be used and others would better be forgotten forever.

It is also important to note that this doesn’t mean that we should drop user acceptance testing (UAT). Even with well though functional unit tests. In general, multiple tests such as automated tests and UAT are complementary to ensure a good test of any development.

Want to learn more? Check out our article Organizations tips for a good Salesforce governance.

Read more posts

Enforce code standards with PMD

Developers working on a project usually set coding rules to have a standardized codebase. It is an important piece of the code maintainability, and it can be very easy …
March 2023
Advices
Scratch orgs

Uncovering Salesforce Settings: A Step-by-Step Guide for Scratch Orgs

Today, it’s pretty easy to build your Scratch Org definition file when you know what Settings you want to activate, as they are mapped with the same setting names …
February 2023
Advices
Business Analyst

Core qualities of a Business Analyst?

A common definition we are used to hear is that being a Business Analyst means to have a combination of both hard skills and soft skills. What does a …
June 2022
Advices
Image d'illustration d'une employée travaillant sur un ordinateur portable

Process builder and workflow make way to Flows (½)

Overview “If you can do it with a Workflow, then do it with a Process Builder, because everything a Workflow does, a Process Builder does it better”. If you …
March 2022
Advices

Day 22 : Salesforce new “Migrate To Flow tool” in Spring 22

As most of you already know, the workflow rules and process builders are planned to be retired in 2023 (no precise date defined so far). Today, I’m going to …
December 2021
Advices

Day 18 : Fake callout responses for test classes !

Hello everybody ! Today let’s talk about Apex tests classes in Salesforce. Everyone loves a good test class, and Salesforce makes it official by requiring to have a minimum …
December 2021
Advices