Comparison

renmy test vs sf apex run test

sf apex run test runs your tests inside a Salesforce org. That makes it the source of truth and the gate every deployment has to clear. renmy runtime runs the same test classes on your machine, with no org at all. It doesn't replace the org run. It removes the org round-trip from the part of the day where you're editing code.

Short version

Use renmy runtime for the runs you trigger on every save, dozens of times an hour. Use sf apex run test where org execution is what you're actually asking about: the final validation before production, and anything that depends on org configuration renmy runtime doesn't replicate. The two run the same @isTest classes from the same repo, so nothing has to be maintained twice.

What each one is

sf apex run test

The Salesforce CLI enqueues a test run in a real org and polls for the result. The org executes against real platform hardware, real org configuration, and real governor limits. Because it runs where your code will eventually live, its verdict is the authoritative one, and the same mechanism backs the test execution inside a deployment. The cost is structural: your changed code has to be in the org first, so a deploy precedes the run, and the run itself waits in the org's queue behind whatever else that org is doing.

renmy test

renmy runtime runs a complete Apex interpreter on your machine against an embedded PostgreSQL. SOQL is translated to real SQL, DML persists, triggers fire in order, flows run from your .flow-meta.xml files, and each test runs in an isolated transaction that is rolled back afterwards. It reads your existing sfdx-project.json and source in place. It needs no org, no credentials, and no network.

Feedback latency

This is the difference you notice most during the day. An org run is deploy time plus queue time plus execution time plus polling; the queue portion is outside your control and varies with what else the org is doing. A local run is execution only.

  • renmy runtime, single test: a typical Apex test completes in tens of milliseconds, SOQL and DML included.
  • renmy runtime, full suite: seconds rather than minutes. The benchmarks publish the method and the numbers for four open-source suites, each run locally and in an org.
  • Org run: deploy the change, enqueue, wait for the queue, then poll for results. Execution time is only one part of it, and usually not the largest one.

The blog post running Apex tests with the Salesforce CLI walks through the flags in detail (test levels, --synchronous, --wait, and recovering a run with sf apex get test), so they are not repeated here.

Org dependency

sf apex run test needs an org to point at: a scratch org from your DevHub, a sandbox, or a developer edition, plus authentication for it and source deployed into it. That's a reasonable requirement for a tool whose job is org execution, but it means the test loop inherits DevHub limits, sandbox refresh cycles, and org availability.

renmy runtime needs none of it. It runs on a plane, on a laptop with no credentials configured, and on a CI runner that was never granted org access. See renmy runtime vs scratch orgs for where that trade stops being free: full platform fidelity is what you give up.

Debugging a failure

After an org run fails, you read what the run left behind: the failure message, the stack trace, and a debug log if you had the right trace flags set. The Apex Replay Debugger can step through that log after the fact.

renmy runtime executes the test on your machine, so a debugger can attach to the live execution: real breakpoints, step in and over, inspect variables with full type information, in VS Code or IntelliJ. Details are on the debugger page, and the model difference is covered in renmy runtime vs the Apex Replay Debugger.

Coverage

An org run with --code-coverage reports line coverage, which is what the platform measures, and it's the number the 75% deployment requirement is checked against. renmy runtime measures line, method, and branch coverage locally during the same test run, and writes HTML, JSON, and Cobertura XML reports plus JUnit XML results.

Branch coverage is the part the org doesn't give you: a line can be covered while one side of its condition has never executed. See local Apex code coverage for the report formats and renmy coverage diff for PR deltas.

CI

Running tests through sf apex run test in CI means the pipeline holds org credentials (a JWT key and connected app, or a scratch org pool provisioned per run), and every job is exposed to org availability and DevHub limits.

A renmy job needs a binary and your repo. The JUnit XML and Cobertura XML it emits are the formats your CI already understands, so the reporting plugs into GitHub Actions, GitLab, SonarQube, or Codecov unchanged. The CI setup page has ready pipeline configs.

What sf does that renmy runtime does not replace

  • The final org validation. Before production, the tests have to pass where the code will run, against real org configuration and real governor-limit accounting. renmy runtime does not claim that verdict; it aims to be the reason you rarely fail it. renmy runtime builds this step into assured deploys: local gates first, then a real Salesforce check-only validation of the exact payload.
  • Deployment itself. Metadata deploys, packaging, org authentication, and data commands are the Salesforce CLI's job, and stay that way.
  • Org-configuration-dependent behaviour. Complex sharing rules and UI rendering need the platform. The comparison matrix is explicit about the gaps.

Both in one toolchain

You don't have to choose a CLI. renmy sf passes any current or future sf command through unchanged (arguments, interactive prompts, and exit codes preserved), so every Salesforce task can start with renmy without losing anything sf can do. If you'd rather keep sf as the entry point, renmy runtime installs as a native Salesforce CLI plugin.

bash
# Inner loop — local, no org
renmy test "InvoiceServiceTest.*"

# The org run, unchanged, through renmy
renmy sf apex run test --tests InvoiceServiceTest --result-format human --wait 20

# Or the other way round: renmy runtime as an sf plugin
sf plugins install @nimbus-solution/nimbus-sf-plugin
sf nimbus apex run test

How the workflow ends up looking

  1. While editing: renmy test, or watch mode re-running affected tests on save. No deploy, no queue.
  2. On the pull request: renmy runtime runs the full suite as the merge gate, publishing JUnit and Cobertura XML.
  3. Before production: the org validates the exact payload, the step that was always the real gate and now the only place an org is required.

Try it against a suite you already run in an org

Point renmy at the same repo you run sf apex run test against and run the same test classes. What passes locally is what you no longer need an org round-trip for. What doesn't shows which tests depend on the platform, which is useful information either way.