Log Entry
RunRelevantTests (Beta)
I have wanted this for ages.
You know the drill: you change one class, kick off a deploy, and then wait while what feels like your entire org test suite runs.
Before this, the options were basically:
RunLocalTests: safe, but often slow in bigger orgs.RunSpecifiedTests: faster when done well, but annoying because you have to manually pick tests (or build tooling to do it).
RunRelevantTests is the new middle ground. Salesforce analyzes your deployment payload and its dependencies, then runs the tests that are relevant to those changes.
Why this feels better day to day
The big win is that test scope tends to scale with what you actually changed.
Small deploy? Usually fewer tests. Big deploy? More tests.
So you keep deployment confidence, but you stop paying the same huge test cost for every tiny change.
Where it is available
RunRelevantTeststest level: available in all API versions.@IsTest(critical=true)and@IsTest(testFor='...'): available in API version66.0+.- Available in Lightning Experience and Salesforce Classic for Enterprise, Performance, Unlimited, and Developer editions.
RunRelevantTestsand related@IsTest()options are pilot/beta services, so beta/pilot terms apply.
How to turn it on
Use whichever deploy path you already have and set the test level to RunRelevantTests:
- Metadata API (file-based deploy): set
DeployOptions.testLevel = RunRelevantTests, then passDeployOptionsintodeploy(). deployRequestREST resource: setdeployOptions.testLeveltoRunRelevantTestsin thePOSTbody.- Salesforce CLI: run
sf project deploy start --test-level RunRelevantTests.
About the new annotations
In most orgs, you probably do not need extra annotations.
The relevance engine usually does the right thing for statically linked code.
If a test should always run
@IsTest(critical=true)
private class PlatformSafetyNetTests {
@IsTest
static void validatesOrgWideBehavior() {
// test body
}
}
If a test should run when specific components change
@IsTest(testFor='ApexClass:InvoiceEngine, ApexTrigger:InvoiceTrigger')
private class InvoiceDynamicFlowTests {
@IsTest
static void validatesDynamicInvocationPath() {
// test body
}
}
My practical rule: only reach for testFor when dependencies are hidden at runtime.
So if you are doing things like dynamic class resolution (Type.forName), metadata-driven routing, or dynamic invocation, that is when testFor helps make sure the right tests still run.
That balance is what I like most here: automatic selection most of the time, explicit control only where dynamic behavior makes dependency detection less obvious.