function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Luke Vang 52Luke Vang 52 

Running Apex Test Async with soap/rest tooling api

Hi,

I'm trying to figure out how to get the results from running test classes asynchrous using the tooling api. It looks like it returns a AsyncApexJob id, but if there a lots of apex tests the process could take a while to complete. How would you know when the job is finished? Would you have to continiously submit get request to find a completion date, or is it possible to create some sort of listener ( without the streaming API ) to listen for when the tests complete?
Raj VakatiRaj Vakati
Hi Luck , 
You can do it with ApexTestQueueItem. I am not sure what exactly you are expecting to do but this might work.  
  1.  You can run tests asynchronously using ApexTestQueueItem and ApexTestResult from the apex Class as shown below.
  2.  Invoke it from the  Apex Scheduler to check the status and alter user.
Refer this link https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_unit_tests_running.htm
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);
            }
        }
    }
}



 
Luke Vang 52Luke Vang 52
I'm not sure this approach works when using the tooling api's test async call in Java. From the documentation it looks like to create the actual listener for the tests, the org would need the streaming api enabled.