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

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 ApexClass ids 
17            String apexTestClassId1 = "01pD00000007M0CIAU"; 
18            String apexTestClassId2 = "01pD00000007NqtIAE";
19            String apexTestSuiteId1 = "05FD00000004CDBMA2";
20            listener.runTests(new String[]{apexTestClassId1, apexTestClassId2}, new String[]{apexTestSuiteId1}, 1);
21         }
22      }
23   };
24);
25//This will subscribe to the TestRun system topic 
26listener = new RunTestListener(client, toolingConn);

Note

1import java.util.HashMap;
2import org.cometd.bayeux.Message;
3import org.cometd.bayeux.client.ClientSessionChannel;
4import org.cometd.bayeux.client.ClientSessionChannel.MessageListener;
5import org.cometd.client.BayeuxClient;
6
7import com.sforce.soap.tooling.ApexTestQueueItem;
8import com.sforce.soap.tooling.ApexTestResult;
9import com.sforce.soap.tooling.QueryResult;
10import com.sforce.soap.tooling.SObject;
11import com.sforce.soap.tooling.SoapConnection;
12import com.sforce.ws.ConnectionException;
13
14public class RunTestListener {
15   private static final String CHANNEL = "/systemTopic/TestResult";
16   private SoapConnection conn;
17
18   public RunTestListener(BayeuxClient client, SoapConnection conn) {
19      this.conn = conn;  
20      System.out.println("Subscribing for channel: " + CHANNEL);  
21      client.getChannel(CHANNEL).subscribe(new MessageListener() {   
22         @Override
23         public void onMessage(ClientSessionChannel channel, Message message) {    
24            HashMap data = (HashMap) message.getData();    
25            HashMap sobject = (HashMap) data.get("sobject");    
26            String id = (String) sobject.get("Id");    
27            System.out.println("\nAysncApexJob " + id);    
28            getTestQueueItems(id);
29         }
30     }); 
31   }
32
33   public void runTests(String[] apexTestClassIds, String[] apexTestSuiteIds, Integer maxFailedTests) {
34      // apexTestClassIds or apexTestSuiteIds is required; maxFailedTests is optional
35      if (apexTestClassIds.length == 0 && apexTestSuiteIds.length == 0) {
36         System.out.println("No test to run");
37         return;
38      }
39      String classIds = null;
40      if (apexTestClassIds.length > 0) {
41         classIds = apexTestClassIds[0];
42         for (int i = 1; i < apexTestClassIds.length; i++) {
43            classIds += "," + apexTestClassIds[i];
44            }
45      }
46      String suiteIds = null;
47      if (apexTestSuiteIds.length > 0) {
48         suiteIds = apexTestSuiteIds[0];
49         for (int i = 1; i < apexTestSuiteIds.length; i++) {
50            suiteIds += "," + apexTestSuiteIds[i];
51         }
52      }
53      try {
54         System.out.println("Running async test run");
55         conn.runTestsAsynchronous(classIds, suiteIds, maxFailedTests);
56      } catch (ConnectionException e) {
57         e.printStackTrace();
58      }
59   }
60
61   private void getTestQueueItems(String asyncApexJobId) {
62      try {   
63         QueryResult res = conn     
64            .query("SELECT Id, Status, ApexClassId FROM ApexTestQueueItem WHERE ParentJobId = '"       
65               + asyncApexJobId + "'");
66         if (res.getSize() > 0) {
67            for (SObject o : res.getRecords()) {     
68               ApexTestQueueItem atqi = (ApexTestQueueItem) o;     
69               System.out.println("\tApexTestQueueItem - "+atqi.getStatus());
70               if (atqi.getStatus().equals("Completed")) {      
71                  getApexTestResults(atqi.getId());     
72               }    
73            }   
74         } else {    
75            System.out.println("No queued items for " + asyncApexJobId);  
76         }  
77      } catch (ConnectionException e) {   
78         e.printStackTrace();  
79      } 
80   }
81
82   private void getApexTestResults(String apexTestQueueItemId) {
83      try {   
84         QueryResult res = conn     
85            .query("SELECT StackTrace,Message, AsyncApexJobId,MethodName, Outcome,ApexClassId FROM ApexTestResult WHERE QueueItemId = '"       
86               + apexTestQueueItemId + "'");
87         if (res.getSize() > 0) {
88            for (SObject o : res.getRecords()) {     
89               ApexTestResult atr = (ApexTestResult) o;     
90               System.out.println("\tTest result for "       
91                  + atr.getApexClassId() + "." + atr.getMethodName());     
92               String msg = atr.getOutcome().equals("Fail") ? " - "       
93                  + atr.getMessage() + " " + atr.getStackTrace() : "";     
94               System.out.println("\t\tTest " + atr.getOutcome() + msg);    
95            }   
96         } else {    
97            System.out.println("No Test Results for " + apexTestQueueItemId);   
98         }  
99      } catch (ConnectionException e) {
100          e.printStackTrace();  
101      } 
102   }
103}