Run Unit Test Methods

To verify the functionality of your Apex code, execute unit tests. You can run Apex test methods in the Developer Console, in Setup, in the Salesforce extensions for Visual Studio Code, or using the API.
You can run these groupings of unit tests.

To run a test, use any of the following:

All Apex tests that are started from the Salesforce user interface (including the Developer Console) run asynchronously and in parallel. Apex test classes are placed in the Apex job queue for execution. The maximum number of test classes that you can run per 24-hour period is the greater of 500 or 10 multiplied by the number of test classes in the org. For sandbox and Developer Edition organizations, this limit is higher and is the greater of 500 or 20 multiplied by the number of test classes in the org.

Note

Note

Apex tests that run as part of a deployment always run synchronously and serially.

Running Tests Through the Salesforce User Interface

You can run unit tests on the Apex Test Execution page. Tests started on this page run asynchronously, that is, you don't have to wait for a test class execution to finish. The Apex Test Execution page refreshes the status of a test and displays the results after the test completes.
Apex Test Execution Page
  1. From Setup, enter Apex Test Execution in the Quick Find box, then select Apex Test Execution.
  2. Click Select Tests....
    Note

    Note

    If you have Apex classes that are installed from a managed package, you must compile these classes first by clicking Compile all classes on the Apex Classes page so that they appear in the list. See Manage Apex Classes.

  3. Select the tests to run. The list of tests includes only classes that contain test methods.
    • To select tests from an installed managed package, select the managed package’s corresponding namespace from the drop-down list. Only the classes of the managed package with the selected namespace appear in the list.
    • To select tests that exist locally in your organization, select [My Namespace] from the drop-down list. Only local classes that aren't from managed packages appear in the list.
    • To select any test, select [All Namespaces] from the drop-down list. All the classes in the organization appear, whether or not they are from a managed package.
    Note

    Note

    Classes with tests currently running don't appear in the list.

  4. To opt out of collecting code coverage information during test runs, select Skip Code Coverage.
  5. Click Run.

After you run tests using the Apex Test Execution page, you can view code coverage details in the Developer Console.

From Setup, enter Apex in the Quick Find box, select Apex Test Execution, then click View Test History to view all test results for your organization, not just tests that you have run. Test results are retained for 30 days after they finish running, unless cleared.

Running Tests Using the Salesforce Extensions for Visual Studio Code

You can execute tests with Visual Studio Code. See Salesforce extensions for Visual Studio Code.

Running Tests Using the Lightning Platform Developer Console

In the Developer Console, you can execute some or all tests in specific test classes, set up and run test suites, or run all tests. The Developer Console runs tests asynchronously in the background, unless your test run includes only one class and you’ve not chosen Always Run Asynchronously in the Test menu. Running tests asynchronously lets you work in other areas of the Developer Console while tests are running. Once the tests finish execution, you can inspect the test results in the Developer Console. Also, you can inspect the overall code coverage for classes covered by the tests.

For more information, see the Developer Console documentation in the Salesforce Help.

Running Tests Using the API

You can use the runTests() call from the SOAP API to run tests synchronously.
RunTestsResult[] runTests(RunTestsRequest ri)
This call allows you to run all tests in all classes, all tests in a specific namespace, or all tests in a subset of classes in a specific namespace, as specified in the RunTestsRequest object. It returns the following.
  • Total number of tests that ran
  • Code coverage statistics
  • Error information for each failed test
  • Information for each test that succeeds
  • Time it took to run the test

For more information on runTests(), see SOAP API and SOAP Headers for Apex.

You can also run tests using the Tooling REST API. Use the /runTestsAsynchronous/ and /runTestsSynchronous/ endpoints to run tests asynchronously or synchronously. For usage details, see Tooling API: REST Resources.

Running Tests Using ApexTestQueueItem

You can run tests asynchronously using ApexTestQueueItem and ApexTestResult. These objects let you add tests to the Apex job queue and check the results of the completed test runs. This process enables you to not only start tests asynchronously but also schedule your tests to execute at specific times by using the Apex scheduler. See Apex Scheduler for more information.

Insert an ApexTestQueueItem object to place its corresponding Apex class in the Apex job queue for execution. The Apex job executes the test methods in the class. After the job executes, ApexTestResult contains the result for each single test method executed as part of the test.

To abort a class that is in the Apex job queue, perform an update operation on the ApexTestQueueItem object and set its Status field to Aborted.

If you insert multiple Apex test queue items in a single bulk operation, the queue items share the same parent job. This means that a test run can consist of the execution of the tests of several classes if all the test queue items are inserted in the same bulk operation.

The maximum number of test queue items, and hence classes, that you can insert in the Apex job queue is the greater of 500 or 10 multiplied by the number of test classes in the org. For sandbox and Developer Edition organizations, this limit is higher and is the greater of 500 or 20 multiplied by the number of test classes in the org.

This example uses DML operations to insert and query the ApexTestQueueItem and ApexTestResult objects. The enqueueTests method inserts queue items for all classes that end with Test. It then returns the parent job ID of one queue item, which is the same for all queue items because they were inserted in bulk. The checkClassStatus method retrieves all queue items that correspond to the specified job ID. It then queries and outputs the name, job status, and pass rate for each class. The checkMethodStatus method gets information of each test method that was executed as part of the job.
public class TestUtil {

    // Enqueue all classes ending in "Test". 
    public static ID enqueueTests() {
        ApexClass[] testClasses = 
           [SELECT Id FROM ApexClass 
            WHERE Name LIKE '%Test'];
        if (testClasses.size() > 0) {
            ApexTestQueueItem[] queueItems = new List<ApexTestQueueItem>();
            for (ApexClass cls : testClasses) {
                queueItems.add(new ApexTestQueueItem(ApexClassId=cls.Id));
            }

            insert queueItems;

            // Get the job ID of the first queue item returned.
            ApexTestQueueItem item = 
               [SELECT ParentJobId FROM ApexTestQueueItem 
                WHERE Id=:queueItems[0].Id LIMIT 1];
            return item.parentjobid;
        }
        return null;
    }

    // Get the status and pass rate for each class
    // whose tests were run by the job.
    // that correspond to the specified job ID.
    public static void checkClassStatus(ID jobId) {
        ApexTestQueueItem[] items = 
           [SELECT ApexClass.Name, Status, ExtendedStatus 
            FROM ApexTestQueueItem 
            WHERE ParentJobId=:jobId];
        for (ApexTestQueueItem item : items) {
            String extStatus = item.extendedstatus == null ? '' : item.extendedStatus;
            System.debug(item.ApexClass.Name + ': ' + item.Status + extStatus);
        }
    }

    // Get the result for each test method that was executed.
    public static void checkMethodStatus(ID jobId) {
        ApexTestResult[] results = 
           [SELECT Outcome, ApexClass.Name, MethodName, Message, StackTrace 
            FROM ApexTestResult 
            WHERE AsyncApexJobId=:jobId];
        for (ApexTestResult atr : results) {
            System.debug(atr.ApexClass.Name + '.' + atr.MethodName + ': ' + atr.Outcome);
            if (atr.message != null) {
                System.debug(atr.Message + '\n at ' + atr.StackTrace);
            }
        }
    }
}