Three levels of apex testing


6 minutes de lecture

Here, we will try to identify three main levels of apex testing when it comes to good and bad practices. However, this is not a “How to” guide for apex testing, it is only intended to give some ideas about how to think our practices. Now let’s dive into the depths of Apex test classes!

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, 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.


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.

A lire également sur le blog


Qu’est-ce que l’agilité ? #1

Avis aux non-sportifs 😱 Non, l’agilité n’est pas une nouvelle astuce des entreprises pour nous faire bouger plus 😉 L’agilité, c’est avant tout un cadre pour les équipes, un …
septembre 2022

Automatically flag emails as spam via flows

Introduction Often when you implement « Email-To-Case » in your organisation, you will quickly be confronted with spam. Receiving a lot of spam can have an impact on your users’ time. …
septembre 2022

Paroles de Texiens : Jason Goolaup !

Portrait de Jason Goolaup, Texien depuis presque 1 an ! Manager et Architecte Technique, découvrez un musicien qui joue autant avec les mélodies qu’avec le code ! …
août 2022
DevOps Center

J’ai testé pour vous : DevOps Center

C’est quoi DevOps Center? DevOps Center est un outil de déploiement de Salesforce qui a été annoncé durant le TrailheadDX 2022. Il est finalement disponible gratuitement en version BETA …
août 2022

Paroles de Texiens : Audrey Riffaud !

Portrait d’Audrey Riffaud, Texienne depuis 3 ans maintenant ! Entre montagne, journalisme et tricotage, découvrez le portrait de notre Directeur Administratif et Financier aux multiples facettes ! …
juillet 2022
Interview Maher

Paroles de Texiens : Maher Ajamane !

Portrait de Maher AJAMANE, Texien depuis 3 ans et demi maintenant ! Consultant le jour, youtubeur et acteur au théâtre le soir, entre la Syrie et la Bretagne, découvrez …
juillet 2022