Why the ApexTestSuite Metadata Type Accelerates Enterprise CI/CD
As a Salesforce org grows past hundreds of Apex classes, running RunLocalTests on every developer pull request creates multi-hour CI/CD bottlenecks. ApexTestSuite (testSuites/<SuiteName>.testSuite-meta.xml) lets architects curate domain-specific collections of Apex test classes (for example, Order_To_Cash_Suite, CPQ_Pricing_Suite, or Nightly_Integration_Regression) directly in version control.
Key Metadata Fields on ApexTestSuite
| Field | Type | Required | Description |
|---|---|---|---|
testClassName |
string[] |
No | List of ApexClass test names or wildcard patterns (Order*Test, *, Namespace.*) included in the suite. |
Real-World XML Example (testSuites/Order_To_Cash_Suite.testSuite-meta.xml)
<?xml version="1.0" encoding="UTF-8"?>
<ApexTestSuite xmlns="http://soap.sforce.com/2006/04/metadata">
<testClassName>OrderCreationServiceTest</testClassName>
<testClassName>OrderTriggerHandlerTest</testClassName>
<testClassName>InvoiceGenerationBatchTest</testClassName>
<testClassName>PaymentGateway*Test</testClassName>
</ApexTestSuite>Running an ApexTestSuite with Salesforce CLI (sf)
# Run one or more ApexTestSuites asynchronously and wait 15 minutes for results
sf apex run test \
--suite-names Order_To_Cash_Suite \
--result-format human \
--code-coverage \
--wait 15Querying ApexTestSuite and TestSuiteMembership via SOQL
In the Salesforce database, suites are stored in ApexTestSuite and linked to ApexClass via the junction object TestSuiteMembership.
1. List All Apex Test Suites and Their Member Classes
SELECT Id, TestSuiteName,
(SELECT ApexClassId, ApexClass.Name FROM TestSuiteMemberships)
FROM ApexTestSuite
ORDER BY TestSuiteName ASC2. Find Test Classes That Are Not Included in Any ApexTestSuite
SELECT Id, Name, ApiVersion, LengthWithoutComments
FROM ApexClass
WHERE NamespacePrefix = null
AND Name LIKE '%Test%'
AND Id NOT IN (SELECT ApexClassId FROM TestSuiteMembership)
ORDER BY Name ASCTip
Audit Orphaned *Test Classes: Running the second SOQL query above in your CI pipeline helps catch newly created *Test classes that developers forgot to add to their domain’s ApexTestSuite!
Frequently asked questions
Why should teams use ApexTestSuite instead of RunLocalTests on every Sandbox pull request?
In large enterprise orgs where RunLocalTests takes 45 to 90 minutes, grouping tests by domain into ApexTestSuite files (such as Billing_Suite or Order_Sync_Suite) lets pull-request validation jobs run targeted tests in minutes via sf apex run test --suite-names.
Does ApexTestSuite support wildcards in testClassName elements?
Yes. Inside a .testSuite-meta.xml file, testClassName supports exact class names (OrderServiceTest), prefix/pattern wildcards (Order*Test), all local tests (*), and managed package namespace wildcards (MyNamespace.*).
Can you use an ApexTestSuite directly inside sf project deploy start --test-level RunSpecifiedTests?
While sf apex run test natively accepts --suite-names, deployment commands (--test-level RunSpecifiedTests) require a comma-separated list of test class names. You can parse your .testSuite-meta.xml file in your CI script to pass the exact class list to --tests.
Can you query ApexTestSuite and its member classes using SOQL?
Yes. Both standard SOQL and the Tooling API allow querying ApexTestSuite (for TestSuiteName) and the junction object TestSuiteMembership (for ApexClassId and ApexTestSuiteId).
Comments
Questions, corrections and tips are welcome. Comments are GitHub Discussions, so you sign in with GitHub.