Salesforce Apex TestingCI

shipfeatures faster

LATdx builds a dependency graph of your Salesforce Apex code and, for each change, finds the exact tests that can reach it. Everything else resolves to a cached result, reused only while nothing in that test's dependency closure has changed.

latdx-demo.sh
$

Zero setup: let LATdx open the PR

Connect the GitHub App and we detect your Salesforce repos and open a pull request that adds the workflow. Already installed? You go straight to your repos. Review, merge, done.

Add to GitHub

Local CLI

Install on your machine

Run LATdx from your terminal to cache Apex test results and skip unchanged reruns.

$curl -fsSL https://latdx.com/install.sh | bash

or read the documentation

One fingerprint per test method

latdx parses your Apex into a dependency graph, hashes everything each test can reach, and reruns a test only when its fingerprint changes. A cached PASS is not a guess: it means nothing that test depends on has changed.

01

Map the reach

The AST links every test method to the code it executes and the metadata that code touches: classes, triggers, fields, validation rules.

02

Fingerprint it

Each test method gets a cache key: a SHA-256 over its whole reach, method bodies, trigger source, field definitions, rules.

03

Rerun only what changed

Same key, same outcome: the result is reused. Any ingredient changed, the test reruns. Fuzzy reach? latdx over-includes and reruns.

AccountServiceTest.clsAccountTriggerTest.clsAccountService.clsAccountTrigger.triggerAccount · schemaDMLtestHappyPathkeye3987368hittestValidatekey13573870hittestRollbackkey11873baahittestBeforeInsertkey2de2a1e8hittestBeforeDeletekeyf7899e98hitvalidate()save() · insert acctrollback()before insert · deleteNameText(80)IndustryPicklistAnnualRevenueCurrencyIndustryRequiredRule
all 5 test methods cached · every fingerprint matches

Click any method, field, trigger or rule to change it. Click a test to inspect its fingerprint.

cache holds
tests rerun
fingerprint

testHappyPath()

sha256(

  • bodytestHappyPath()5308da80
  • apexAccountService.validate()deb4f9cc
  • apexAccountService.save()011de9b7
  • objAccount objects/**073638ff
  • metashared manifest7e6f7d94

)

= keye3987368

matches the stored entry → result reused, test not sent to the org

Every ingredient is hashed from the parsed AST or the metadata XML. If any line above changes, the key changes, and the cached result is never used again.

shared manifest = triggers · flows · workflow + validation rules · labels · custom metadata · profiles · permission sets · sharing rules. One edit there reruns everything, the same cost as a run without LATdx.

Comments and formatting never invalidate: keys are hashed from the token stream, not file bytes.

Metadata counts: a field, rule, flow or trigger edit reruns every test it could possibly affect.

When reach cannot be proven statically, latdx over-includes and reruns. False cache hits are designed out.

How the cache answers the hard cases

how-it-works.faq
Early access

Lock in launch pricing

Subscribe today and keep your rate for the life of the subscription. New subscribers pay double after launch.

Cancel anytimeNo card for FreeProrated immediatelyEarly access price locked

Free

$0forever

100 tests / run. No card required.

  • Method-level caching
  • Live test results
  • PR-related tests only
  • 100 tests per run
  • Watch mode
  • Run tests in CI

Pro

$20$10/ mo

Unlimited tests on your machine.

  • Method-level caching
  • Live test results
  • PR-related tests only
  • Unlimited tests per run
  • Watch modeComing soon
  • Run tests in CI

TEAM/CI

$200$100/ mo

CI license. 5 Pro seats included.

  • Method-level caching
  • Live test results
  • PR-related tests only
  • Unlimited tests per run
  • Watch modeComing soon
  • Run tests in CI
PRO Seats

Common questions

pricing.faq