Log Entry

RunRelevantTests (Beta)

Feb 23, 2026 · 5 min read

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

  • RunRelevantTests test level: available in all API versions.
  • @IsTest(critical=true) and @IsTest(testFor='...'): available in API version 66.0+.
  • Available in Lightning Experience and Salesforce Classic for Enterprise, Performance, Unlimited, and Developer editions.

RunRelevantTests and 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 pass DeployOptions into deploy().
  • deployRequest REST resource: set deployOptions.testLevel to RunRelevantTests in the POST body.
  • 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.