Configuration

The whole test environment in one file

In Salesforce, the test environment lives in Setup, Custom Settings and org-level metadata. None of it is in source control, and none of it reaches your team automatically. Nimbus reads all of it from one properties file you commit.

nimbus.properties

Put a nimbus.properties file in the project root and commit it. Every developer on the team then runs with the same database settings, governor limit enforcement, org defaults, custom setting seeds and tracing preferences, with nothing to configure by hand.

If you have used application.properties in Spring Boot or Quarkus, the format is the same. The configuration lives in your repo instead of in an org.

properties
# nimbus.properties - commit this to your repo

# Governor limits: catch violations before they reach the org
nimbus.governor.mode=warn

# Org environment defaults
nimbus.org.currency=EUR
nimbus.org.locale=de_DE
nimbus.org.timezone=Europe/Berlin

# Seed custom setting org defaults
nimbus.seed.org-default.TriggerSettings__c=IsEnabled__c=true
nimbus.seed.org-default.AppConfig__c=Endpoint__c=https://api.example.com,Retries__c=3

# Testing
nimbus.test.parallel=4
nimbus.test.timeout=30s

# Tracing (disabled by default, enable when debugging)
nimbus.trace.enabled=false
nimbus.trace.level=normal

Profiles for local, CI and staging

Your local machine, your CI pipeline and your staging environment need different settings. A profile is a set of overrides for one of those contexts, defined in the same file. There are no separate config files and no environment-specific branches.

Prefix any property with %profile. to create a profile-specific override. Activate a profile with NIMBUS_PROFILE=ci or --profile ci. Properties without a prefix apply everywhere. Profile-specific values override the defaults.

properties
# Default: relaxed for local development
nimbus.governor.mode=warn
nimbus.trace.enabled=true
nimbus.trace.level=verbose

# CI: strict enforcement, no browser
%ci.nimbus.governor.mode=strict
%ci.nimbus.test.parallel=2
%ci.nimbus.trace.enabled=false
%ci.nimbus.devui.open-browser=false

# Staging: production-like limits
%staging.nimbus.governor.mode=strict
%staging.nimbus.test.timeout=120s
bash
# Activate a profile
NIMBUS_PROFILE=ci nimbus test

# Or via CLI flag
nimbus test --profile ci

Environment variable interpolation

Reference environment variables in your properties file with ${VAR} syntax. Add a default value with ${VAR:default}. This keeps secrets out of your committed config while still sharing the structure with your team.

properties
# Use environment variables for secrets
nimbus.db.url=${DATABASE_URL}
nimbus.db.password=${DB_PASSWORD:localdev}

# CI can set these, local dev uses defaults
nimbus.org=${SF_ORG:default}

Configuration hierarchy

Nimbus loads properties from three levels. Later levels override earlier ones, so an admin can set system-wide defaults and a project overrides what it needs.

system
System-wide/etc/nimbus/nimbus.propertiesCompany-wide defaults set by an admin. Lowest priority.
user
User-level~/.nimbus/nimbus.propertiesPersonal preferences: your timezone, your editor port, your trace level.
project
Project-level./nimbus.propertiesCommitted to git and shared with the team. Highest priority.

Custom Setting seeds

Many Apex codebases read configuration from Custom Settings: feature flags, endpoint URLs, retry counts. In an org they are set through Setup. Locally you would need a @testSetup method in every test class to insert them.

With nimbus.seed.org-default, you define the org-default values once in the properties file. Every test sees them without a @testSetup method, and the values are the same on every machine. Read them the same way as on the platform: MySettings__c.getOrgDefaults().

properties
# Seed org-default custom settings in nimbus.properties
nimbus.seed.org-default.TriggerSettings__c=IsEnabled__c=true,RunValidation__c=true
nimbus.seed.org-default.IntegrationConfig__c=Endpoint__c=https://api.example.com,ApiKey__c=test-key
nimbus.seed.org-default.FeatureFlags__c=EnableNewUI__c=false,EnableBetaFeatures__c=true

Org defaults can also be passed on the CLI, for one-off runs or CI overrides that should not touch the properties file:

bash
# Seed via CLI flag (repeatable for multiple objects)
nimbus test --org-default "TriggerSettings__c.IsEnabled__c=true"
nimbus test --org-default "AppConfig__c.Endpoint__c=https://api.example.com,Retries__c=3"

Permissions, metadata, and record types

Nimbus reads the project's metadata alongside the Apex. Permission Sets load from .permissionset-meta.xml files. Custom Metadata Types are discovered from .md-meta.xml files and can be queried with SOQL. Record Types are seeded from the project structure.

System.runAs() works locally. Set up a user with specific Permission Set assignments and test that your code respects object permissions, field-level security and SOQL WITH USER_MODE access checks, without an org.

Permission-dependent logic (does this profile see this field, does this user have create access) is testable on your machine, in milliseconds.

apex
// Test permission-based logic locally
@isTest
static void testRestrictedAccess() {
    // Create a user with specific permissions
    User restrictedUser = new User(
        ProfileId = restrictedProfileId,
        Username = 'test@nimbus.dev'
    );

    System.runAs(restrictedUser) {
        // Your code runs with this user's
        // object and field permissions
        try {
            insert new Account(Name = 'Test');
            System.assert(false, 'Should have failed');
        } catch (DmlException e) {
            // Permission enforced locally
        }
    }
}
properties
# Auto-seed RecordTypes from project metadata
nimbus.seed.record-types=true

# Set default RecordType per object for inserts
# without explicit RecordTypeId (mirrors profile defaults)
nimbus.default-record-type.Lead=Prospect_Record_Type
nimbus.default-record-type.Case=Support_Case

# Seed ListViews not in your repo metadata
# (standard objects have built-in views in Salesforce)
nimbus.seed.list-view.Lead.AllLeads=All Leads
nimbus.seed.list-view.Lead.MyLeads=My Leads

# Custom Metadata Types are auto-discovered
# from your force-app/.../customMetadata/ dir
# and queryable via SOQL in tests

Generating a starter file

Run nimbus config init to write a documented nimbus.properties file with every available property, its description and example profiles. Uncomment what you need and commit the file.

bash
# Generate a documented nimbus.properties file
nimbus config init

# See current effective configuration (with sources)
nimbus config show

# List all available properties
nimbus config properties

Property reference

All 35 configuration properties, grouped by category.

Database

Where Nimbus stores test data: embedded PostgreSQL, Docker, or an external instance.

PropertyTypeDefaultDescription
nimbus.db.providerstringembeddedDatabase provider: embedded, docker, or external
nimbus.db.urlstring-PostgreSQL connection string (overrides provider)
nimbus.db.namestring(auto)Database name override
nimbus.db.dirstring.nimbus/dbEmbedded Postgres data directory
nimbus.db.pool.max-connectionsint100Maximum database connections
nimbus.db.pool.idle-timeoutduration1mConnection idle timeout
nimbus.db.lock-timeoutduration5sDatabase lock timeout

Testing

How tests execute: parallelism, timeouts, exclusions.

PropertyTypeDefaultDescription
nimbus.test.parallelint(NumCPU)Number of parallel test workers
nimbus.test.timeoutduration60sTimeout per test method
nimbus.test.fallback-to-cliboolfalseFall back to Salesforce CLI for unsupported features
nimbus.test.excludelist-Exclude patterns (comma-separated)

Tracing

Execution traces: enable them, set the verbosity, choose the output location.

PropertyTypeDefaultDescription
nimbus.trace.enabledboolfalseEnable execution tracing
nimbus.trace.levelstringnormalTrace verbosity: minimal, normal, verbose, debug, system
nimbus.trace.outputstring.nimbus/tracesDirectory for trace output files
nimbus.trace.max-value-lengthint1000Maximum value length in traces

Governor Limits

Salesforce governor limits enforced locally, so violations show up before the code reaches the org.

PropertyTypeDefaultDescription
nimbus.governor.modestringwarnEnforcement mode: strict (fail), warn (log), off
nimbus.governor.soql-queriesint100SOQL query limit per transaction
nimbus.governor.dml-statementsint150DML statement limit per transaction
nimbus.governor.heap-sizeint12000000Heap size limit in bytes

Org & Mock Data

The simulated org environment: currency, locale, timezone, user identity and custom setting defaults.

PropertyTypeDefaultDescription
nimbus.org.currencystringUSDDefault currency for UserInfo.getDefaultCurrency()
nimbus.org.localestringen_USDefault locale for UserInfo.getLocale()
nimbus.org.timezonestringAmerica/Los_AngelesDefault timezone
nimbus.mock.user-idstring005000000000000AAAMock user ID for CreatedById / LastModifiedById
nimbus.seed.record-typesbooltrueAuto-seed RecordTypes from project metadata
nimbus.seed.org-default.<Object>string-Seed custom setting org defaults (see examples below)
nimbus.default-record-type.<Object>string-Default RecordType DeveloperName for inserts without explicit RecordTypeId
nimbus.seed.list-view.<Object>.<DevName>string-Seed a ListView record (value is the label)

Project

General project settings: default org, caching, output verbosity.

PropertyTypeDefaultDescription
nimbus.orgstringdefaultDefault Salesforce org alias (for nimbus sync)
nimbus.cache.dirstring.nimbus/cacheAST cache directory
nimbus.verboseboolfalseVerbose CLI output

Dev UI & Daemon

The browser-based Dev UI and the background daemon.

PropertyTypeDefaultDescription
nimbus.devui.portint8080Dev UI server port
nimbus.devui.open-browserbooltrueOpen browser automatically on nimbus dev
nimbus.daemon.auto-startboolfalseAuto-start daemon on test run for warm caches

Configuration that lives in your repo

Run nimbus config init and commit the file. From then on the test environment is configured from the repo.