Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>aer Local Apex DebuggerNew to Visual Studio Code? Get it now.
aer Local Apex Debugger

aer Local Apex Debugger

October Swimmer

octoberswimmer.com
|
170 installs
| (0) | Free
Debug Apex locally with aer
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

aer Local Apex Debugger

Debug Apex locally with aer using VS Code's built-in debugging interface, and get language features like autocompletion, hover information, and go-to-definition.

Features

Debugging Features

  • Debug Apex tests locally
  • Debug anonymous Apex code
  • Set breakpoints in Apex classes and triggers
  • Step through code (step in, step over, step out)
  • Inspect variables (locals, instance fields, static fields)
  • Evaluate Apex expressions in the debug console
  • View call stack with line numbers

Testing Features

  • Run and debug Apex unit and integration tests from the Testing view
  • Continuous testing with a watch profile
  • Apex code coverage shown in the editor gutter and the Test Coverage view

Language Features (LSP)

  • Semantic syntax highlighting for Apex
  • Autocompletion for Apex classes, methods, and fields
  • Hover information for symbols
  • Go to definition
  • Find references
  • Document symbols

Requirements

  • aer must be installed and available in your PATH (the extension will offer to download the latest release if it cannot find aer)
  • VS Code 1.88.0 or later

The extension will periodically check GitHub for newer aer releases and prompt you to update the locally cached binary when one is available.

When the extension downloads aer for you, it adds the download directory to the PATH of VS Code's integrated terminal, so you can run aer directly from terminals you open afterwards. The download directory is appended to PATH, so an aer you have installed elsewhere on your PATH still takes precedence.

Installation

The VS Code extension is automatically installed when you run aer with debugging enabled for the first time. No manual installation is required.

When you run a debug command (such as aer test --debug or aer exec --debug), aer will:

  1. Check if the extension is installed in VS Code
  2. Automatically install or update the extension if needed
  3. Start the debug session

The extension will be available in VS Code's Extensions view as "aer Local Apex Debugger".

Configuration

You can configure the extension in your VS Code settings (optional):

{
	"aer.path": "/path/to/aer"
}

Configuration Options

  • aer.path: Path to the aer executable (default: "aer", uses PATH)

    • Optional: only needed if aer is not in your PATH
  • aer.useSfdxProject: Use sfdx-project.json when present (default: true)

    • This setting has resource scope, so it can be set per-workspace in .vscode/settings.json
    • When enabled and an sfdx-project.json is found at or above the workspace, the extension derives — mirroring the aer sf plugin:
      • packageDirectories → the source paths passed to the language server, test runner, and debugger
      • namespace → the default namespace (--default-namespace)
      • replacements → applied by staging source into a temporary directory (with the string/regex substitutions) before running, matching what sf project deploy start would deploy. replaceWithEnv, replaceWithFile, replaceWhenEnv, and allowUnsetEnvVariable are all honored.
      • unpackagedMetadata → each packageDirectories entry's unpackagedMetadata.path is loaded (and, when replacements are in effect, staged) alongside the packaged source, so tests compile and run against that metadata just as they would during package version creation.
      • apexTestAccess.permissionSets → passed to aer as --assign-perms (combined with the aer.assignPermissionSets setting) so tests run with those permission sets assigned to the test user. apexTestAccess.permissionSetLicenses has no local equivalent in aer and is ignored with a warning in the test runner output.
    • Explicit aer.sourcePaths and aer.defaultNamespace settings still take precedence over the values from sfdx-project.json.
    • Notes on replacements:
      • The language server always edits your live files, so replacements are not applied to language features — only packageDirectories and namespace are.
      • In Watch mode, edits to your real source files are mirrored into the staging directory so tests re-run with substitutions re-applied.
      • Hand-authored launch.json debug configurations use packageDirectories and namespace but do not stage replacements; use the Test Explorer's Debug action to debug with replacements applied.
    • Set to false to ignore sfdx-project.json entirely and rely on automatic project-root detection (or explicit aer.sourcePaths).
  • aer.asNamespace: Treat loaded code as if it belongs to the specified namespace (default: "")

    • Useful for managed package development where your code references namespaced custom objects and fields using its own namespace
    • This setting has resource scope, so it can be set per-workspace in .vscode/settings.json
    • Example for a managed package with namespace oslog:
      {
        "aer.asNamespace": "oslog"
      }
      
    • When set, the LSP server, test runner, and debugger will:
      • Treat all Apex classes as belonging to the namespace
      • Apply the namespace prefix to custom objects and fields in the schema
      • Resolve references like oslog__MyObject__c and oslog__MyField__c
  • aer.lsp.sourcePaths: Specific directories to scan for Apex files (default: [])

    • Usually not needed - the LSP server automatically detects project roots
    • When you open an Apex file, the server walks up the directory tree looking for:
      1. sfdx-project.json (SFDX projects)
      2. package.xml (Metadata API projects)
      3. If the file is in a classes or triggers directory, uses the parent directory
    • Only set this if you need to override the automatic detection
    • Example (rarely needed):
      {
        "aer.lsp.sourcePaths": [
          "/custom/path/to/apex/files"
        ]
      }
      
  • aer.lsp.trace: Trace communication between VS Code and the aer language server (default: "off")

    • Useful for debugging LSP issues
    • Values: "off", "messages", "verbose"
    • Trace output goes to a separate "aer Language Server Trace" output channel
    • Example:
      {
        "aer.lsp.trace": "verbose"
      }
      

Usage

Quick Start - Debugging Tests

The fastest way to debug Apex tests is from the command line:

  1. Open a terminal in your Apex project directory
  2. Run aer with debugging enabled:
    aer test --debug ./force-app/main/default/classes
    
  3. VS Code will automatically open and connect to the debugger
  4. The debugger will pause at the first line of your test (stopOnEntry mode)
  5. Set breakpoints by clicking in the gutter next to line numbers
  6. Use the debug controls to step through your code (F5=Continue, F10=Step Over, F11=Step Into)

Quick Start - Debugging Anonymous Apex

  1. Run aer exec --debug from your project directory (optional: pass a snippet to prefill the prompt, e.g. aer exec --debug "Integer x = 5; System.debug('x = ' + x);").
  2. VS Code opens with a "Debug Anonymous Apex" configuration; press F5 and enter your Apex code when prompted.
  3. The debugger stops on entry so you can set breakpoints and step through the code.

You can:

  • Set breakpoints in the "Anonymous Apex" source view
  • Step through your code using the debug controls

Running Apex Tests in VS Code

You can run and debug Apex tests directly from VS Code's Testing view (beaker icon) using the built-in Apex test controller:

  1. Open your project in VS Code and make sure aer is on your PATH (or set aer.path in settings).
  2. Open the Testing view. The extension discovers .cls files with test methods and populates the Apex Tests tree, split into Unit Tests (@IsTest/testMethod) and Integration Tests (@IntegrationTest).
  3. Use the run (triangle) or debug (bug) icons in the tree or inline next to a class/method to execute just that scope. The top-level controls run or debug everything under the selected workspace folder.
  4. Results show inline and in the Testing panel with pass/fail status, durations, and error messages linked to file locations (the extension runs aer test --json under the hood). Tests with no pass/fail result — e.g. when a run is stopped before they execute — are marked skipped rather than failed.
  5. Debug runs start aer test --debug ... and stop on entry so you can immediately hit breakpoints in your tests.

Integration tests run under aer's commit-semantics mode with @TearDown cleanup. When you run or debug an integration test, the extension passes --integration-tests automatically. A selection that spans both groups is executed as two runs (unit tests, then integration tests), since the two modes are mutually exclusive.

Because integration tests commit data and each starts its own debug session, the Debug Apex Tests profile skips them on a top-level "debug all" — debug an integration test by selecting its class, method, or the Integration Tests group explicitly. (Running and watching include integration tests in a blanket run.)

When a workspace contains both unit and integration tests, the debug action on the top-level aer node is hidden (debugging a mix in one session is ambiguous); the debug action remains available on the Unit Tests / Integration Tests groups and on individual classes and methods. The aer node keeps its debug action when only one kind of test is present.

Code Coverage

The extension can collect Apex code coverage while running tests:

  1. Open the Testing view (beaker icon).
  2. Click the dropdown arrow next to the run button and select Run Apex Tests with Coverage, or use the editor's built-in Run with Coverage action.
  3. Run any scope — a method, a class, a group, or everything.
  4. When the run finishes, covered and uncovered lines are shown in the editor gutter, and per-file coverage totals appear in the Test Coverage panel and as coverage decorations in the Explorer.

Coverage is collected by passing --coverage to aer test; only the classes exercised by the selected tests are reported. A selection spanning both unit and integration tests merges the coverage from both runs, with a line counted as covered if it was executed by either.

Watch Mode (Continuous Testing)

The extension supports a Watch Apex Tests run profile that continuously monitors your source files and re-runs tests whenever changes are detected:

  1. Open the Testing view (beaker icon)
  2. Click the dropdown arrow next to the run button and select Watch Apex Tests
  3. Run your tests - they will execute immediately
  4. Edit any .cls or .trigger file and save - tests automatically re-run
  5. Cancel the test run to stop watching

Watch mode is useful for test-driven development workflows where you want immediate feedback as you make changes. The test results update in real-time as each test run completes.

License Registration

When aer hits a license limit (test limit or 5-minute debug limit), the extension shows a prompt with:

  • Subscribe
  • Register License
  • Show Current License
  • Manage Subscription

To show this prompt manually at any time:

  1. Open Command Palette (Ctrl+Shift+P / Cmd+Shift+P)
  2. Run aer: License Management

To show current license details (aer license show) in VS Code:

  1. Open Command Palette
  2. Run aer: Show aer License
  3. The extension opens a text editor with the command output

To go directly to key entry:

  1. Open Command Palette
  2. Run aer: Register aer License
  3. Enter your registration key
  4. Enter email address (required)

CLI registration:

aer license register <registration-key> --email developer@example.com

Using Language Features

The extension automatically starts the Apex language server when you open an Apex file (.cls or .trigger). You'll have access to:

  • Autocompletion: Press Ctrl+Space to trigger IntelliSense
  • Hover Information: Hover over a symbol to see its documentation
  • Go to Definition: F12 or Ctrl+Click to jump to a symbol's definition
  • Find References: Shift+F12 to find all references to a symbol
  • Document Symbols: Ctrl+Shift+O to see all symbols in the current file

Debugging Features

Breakpoints

  • Click in the gutter to set/remove breakpoints
  • Breakpoints are verified when the debug session starts
  • Conditional breakpoints and logpoints are not yet supported

Stepping

  • Step Over (F10): Execute the current line and move to the next line
  • Step Into (F11): Step into method calls
  • Step Out (Shift+F11): Step out of the current method
  • Continue (F5): Continue execution until the next breakpoint

Variable Inspection

The Variables view shows:

  • Locals: Local variables in the current method
  • This: Instance fields of the current object
  • Static: Static fields of the current class

Hover over variables in the editor to see their values.

Watch Expressions

Add Apex expressions to the Watch view to evaluate them:

  • myVar.size()
  • this.expectedValue
  • MyClass.staticField

Debug Console

Evaluate Apex expressions in the Debug Console:

> myList.get(0)
> this.accountName
> System.now()

Call Stack

The Call Stack view shows:

  • Current execution location
  • Method call hierarchy
  • File names and line numbers

Troubleshooting

"Failed to start aer" error

Make sure aer is installed and in your PATH:

which aer
aer --version

"Failed to connect to aer debug server"

This usually means aer couldn't start or the DAP server didn't initialize. Check:

  1. The path you provided contains test classes or valid Apex code
  2. aer can run tests normally: aer test ./your-test-path

Breakpoints not working

  1. Make sure you're setting breakpoints in .cls files that are being executed
  2. Verify the file path matches between VS Code and the test execution
  3. Check that the line has executable code (not comments or blank lines)

Variables show as "undefined"

This can happen if:

  • You're viewing variables from a frame that hasn't been fully initialized
  • The variable hasn't been assigned yet in the execution flow
  • Static fields haven't been initialized

Examples

Example Test Class

@isTest
public class MyTest {
	@TestSetup
	static void setup() {
		Account acc = new Account(Name = 'Test');
		insert acc;
	}

	@isTest
	static void testAccountCreation() {
		List<Account> accounts = [SELECT Id, Name FROM Account];
		System.assertEquals(1, accounts.size());
		System.assertEquals('Test', accounts[0].Name);
	}
}

Set a breakpoint on the System.assertEquals line and run the debugger. When it pauses:

  • Inspect accounts in the Variables view
  • Add accounts.size() to the Watch view
  • Step through the assertions

Known Limitations

  • Debugging sessions without a valid license are limited to 5 minutes
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft