Newer Version Available

This content describes an older version of this product. View Latest

ApexTestQueueItem

Represents a single Apex class in the Apex job queue. Available in API version 30.0 and later.

Supported SOAP API Calls

create()describeSObjects()query()retrieve()update()upsert()

Supported REST API HTTP Methods

Query, GET, POST, PATCH

Fields

Field Name Details
ApexClassId
Type
reference
Properties
Create, Filter, Group, Sort
Description

The Apex class whose tests are to be executed.

This field can't be updated.

Status
Type
picklist
Properties
Filter, Group, Restricted picklist, Sort, Update
Description
The status of the test. Valid values are:
  • Queued
  • Processing
  • Aborted
  • Completed
  • Failed
  • Preparing
  • Holding

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.

ExtendedStatus
Type
string
Properties
Filter, Nillable, Sort
Description

The pass rate of the test run.

For example: “(4/6)”. This means that four out of a total of six tests passed.

If the class fails to execute, this field contains the cause of the failure.

ParentJobId
Type
reference
Properties
Filter, Group, Nillable, Sort
Description

Read-only. Points to the AsyncApexJob that represents the entire test run.

If you insert multiple Apex test queue items in a single bulk operation, the queue items will 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.
ShouldSkipCodeCoverage
Type
boolean
Properties
Create, Defaulted on create, Filter, Group, Sort, Update
Description

Indicates whether to opt out of collecting code coverage information during Apex test runs. Available in API version 43.0 and later.

TestRunResultID
Type
reference
Properties
Filter, Group, Nillable, Sort
Description

The ID of the associated ApexTestRunResult object. Available in API version 37.0 and later.

Usage

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.

The example RunTestListener.java class below subscribes to the TestResult system topic and prints out the test results using ApexTestQueueItem and ApexTestResult. The example assumes the following:
  • You have already set up a Java client application for Streaming API. This example uses the org.cometd.client.BayeuxClient created in the Java Client code example in the Streaming API Developer Guide.
  • You have a logged in com.sforce.soap.tooling.SoapConnection. For examples, see the SOAP API Developer Guide.
The RunTestListener.java class must be instantiated after the Streaming API handshake. For example:
1SoapConnection toolingConn; //Already set and logged in
2BayeuxClient client; //Already set and logged in
3
4//Listen on the handshake event 
5boolean handshaken = client.waitFor(10 * 1000, BayeuxClient.State.CONNECTED); 
6if (!handshaken) {
7   System.out.println("Failed to handshake: " + client); 
8   System.exit(1); 
9} 
10final RunTestListener = null; 
11client.getChannel(Channel.META_SUBSCRIBE).addListener( 
12   new ClientSessionChannel.MessageListener() { 
13      public void onMessage(ClientSessionChannel channel, Message message) { 
14         boolean success = message.isSuccessful(); 
15         if (success) { 
16            //Replace with your own classes and suites
17            String apexTestClassId1 = "01pD00000007M0CIAU"; 
18            String apexTestClassId2 = "01pD00000007NqtIAE";
19            String apexTestSuiteId1 = "05FD00000004CDBMA2";
20            String apexTestClassName1 = "Test_MyClass";
21            String apexTestSuiteName1 = "TestSuite_MySuite";
22            listener.runTests(new String[]{apexTestClassId1, apexTestClassId2},
23               new String[]{apexTestSuiteId1}, 1, new String[]{apexTestClassName1},
24               new String[]{apexTestSuiteName1});
25         }
26      }
27   };
28);
29//This will subscribe to the TestRun system topic 
30listener = new RunTestListener(client, toolingConn);

Note

1import java.util.HashMap;
2import org.apache.commons.lang3.StringUtils;
3import org.cometd.bayeux.Message;
4import org.cometd.bayeux.client.ClientSessionChannel;
5import org.cometd.bayeux.client.ClientSessionChannel.MessageListener;
6import org.cometd.client.BayeuxClient;
7
8import com.sforce.soap.tooling.ApexTestQueueItem;
9import com.sforce.soap.tooling.ApexTestResult;
10import com.sforce.soap.tooling.QueryResult;
11import com.sforce.soap.tooling.SObject;
12import com.sforce.soap.tooling.SoapConnection;
13import com.sforce.soap.tooling.TestLevel;
14import com.sforce.ws.ConnectionException;
15
16public class RunTestListener {
17   private static final String CHANNEL = "/systemTopic/TestResult";
18   private SoapConnection conn;
19
20   public RunTestListener(BayeuxClient client, SoapConnection conn) {
21      this.conn = conn;  
22      System.out.println("Subscribing for channel: " + CHANNEL);  
23      client.getChannel(CHANNEL).subscribe(new MessageListener() {   
24         @Override
25         public void onMessage(ClientSessionChannel channel, Message message) {    
26            HashMap data = (HashMap) message.getData();    
27            HashMap sobject = (HashMap) data.get("sobject");    
28            String id = (String) sobject.get("Id");    
29            System.out.println("\nAysncApexJob " + id);    
30            getTestQueueItems(id);
31         }
32     }); 
33   }
34
35   public void runTests(String[] apexTestClassIds, String[] apexTestSuiteIds,
36      Integer maxFailedTests, String[] apexTestClassNames, String[] apexTestSuiteNames) {
37
38      // All parameters are required
39
40      if (apexTestClassIds == null && apexTestSuiteIds == null
41         && apexTestClassNames == null && apexTestSuiteNames == null) {
42         System.out.println("No tests to run");
43         return;
44      }
45      String classIds = StringUtils.join(apexTestClassIds,", ");
46      String suiteIds = StringUtils.join(apexTestSuiteIds,", ");
47      String classNames = StringUtils.join(apexTestClassNames,", ");
48      String suiteNames = StringUtils.join(apexTestSuiteNames,", ");
49
50      String tests = null;
51      Boolean skipCodeCover = false;
52
53      try {
54         System.out.println("Running async test run");
55         conn.runTestsAsynchronous(classIds, suiteIds, maxFailedTests,
56            TestLevel.RunSpecifiedTests, classNames, suiteNames, tests, skipCodeCover);
57      } catch (ConnectionException e) {
58         e.printStackTrace();
59      }
60   }
61   public void createAndRunTestsNode(String apexTestClassName,
62      String apexTestClassId, String[] apexTestMethods) {
63
64      //Currently, the array size of TestNode objects must be 1
65
66      //Provide a non-null class name or a non-null class ID
67      if (apexTestClassName != null && apexTestClassId != null) {
68         System.out.println("Specify a class name OR a class ID");
69         return;
70      } else if (apexTestClassName == null && apexTestClassId == null) {
71         System.out.println("No tests to run");
72         return;
73      }
74
75      TestsNode thisTestsNode = new TestsNode();
76      thisTestsNode.setClassName(apexTestClassName);
77      thisTestsNode.setClassId(apexTestClassId);
78      thisTestsNode.setTestMethods(apexTestMethods);
79      TestsNode[] tests = new TestsNode[] { thisTestsNode };
80
81      try {
82         System.out.println("Running async test run");
83         conn.runTestsAsynchronous(null, null, -1, null, null, null, tests);
84      } catch (ConnectionException e) {
85         e.printStackTrace();
86      }
87   }
88
89   private void getTestQueueItems(String asyncApexJobId) {
90      try {   
91         QueryResult res = conn     
92            .query("SELECT Id, Status, ApexClassId FROM ApexTestQueueItem
93               WHERE ParentJobId = '" + asyncApexJobId + "'");
94         if (res.getSize() > 0) {
95            for (SObject o : res.getRecords()) {     
96               ApexTestQueueItem atqi = (ApexTestQueueItem) o;     
97               System.out.println("\tApexTestQueueItem - "+atqi.getStatus());
98               if (atqi.getStatus().equals("Completed")) {      
99                  getApexTestResults(atqi.getId());     
100               }    
101            }   
102         } else {    
103            System.out.println("No queued items for " + asyncApexJobId);  
104         }  
105      } catch (ConnectionException e) {   
106         e.printStackTrace();  
107      } 
108   }
109
110   private void getApexTestResults(String apexTestQueueItemId) {
111      try {   
112         QueryResult res = conn     
113            .query("SELECT StackTrace,Message, AsyncApexJobId,MethodName, Outcome,ApexClassId
114               FROM ApexTestResult WHERE QueueItemId = '" + apexTestQueueItemId + "'");
115         if (res.getSize() > 0) {
116            for (SObject o : res.getRecords()) {     
117               ApexTestResult atr = (ApexTestResult) o;     
118               System.out.println("\tTest result for "       
119                  + atr.getApexClassId() + "." + atr.getMethodName());     
120               String msg = atr.getOutcome().equals("Fail") ? " - "       
121                  + atr.getMessage() + " " + atr.getStackTrace() : "";     
122               System.out.println("\t\tTest " + atr.getOutcome() + msg);    
123            }   
124         } else {    
125            System.out.println("No Test Results for " + apexTestQueueItemId);   
126         }  
127      } catch (ConnectionException e) {
128          e.printStackTrace();  
129      } 
130   }
131}