Testing in Golem

SkillDev tools

Running and debugging tests in the Golem workspace. Use when writing tests, running specific tests, filtering tests, debugging test failures, or understanding test infrastructure.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Testing in Golem skill

What this skill tells your AI

The instructions your AI receives, as published by golemcloud/golem in .agents/skills/testing/SKILL.md and read by ahel’s review.

Root-workspace Rust tests use test-r. Each test crate or integration-test entry point using test-r must call test_r::enable!(), and test_r::test must be in lexical scope wherever #[test] is used. Separate workspaces may have their own harness setup.

#[cfg(test)]
test_r::enable!();

#[cfg(test)]
mod tests {
    use test_r::test;

    #[test]
    fn my_test() {
        // ...
    }
}

Choosing the Right Test Command

Do not run cargo make test — it runs broad root-workspace unit, worker-executor, service, and CLI integration suites and takes a very long time.

Change TypeTest Command
Core logic, utilitiescargo make unit-tests
Worker executor functionalitycargo make worker-executor-tests
Broad service and CLI integrationcargo make integration-tests
CLI changescargo make cli-integration-tests
CLI structured output/schemacargo test -p golem-cli cli_output_schema_ --lib + cargo make check-cli-output-schema

Whenever tests are modified, always run the affected tests to verify they still pass before considering the task complete.

For running specific tests during development:

cargo test -p <crate> -- <test_name> --report-time

For golem-cli structured output schema or generator changes, load the modifying-cli-output-schema skill. If arbitrary output generators changed, rerun this prop test a few times to catch generator/schema drift:

cargo test -p golem-cli cli_output_schema_accepts_registered_generated_examples --lib -- --report-time

If CLI JSON output field names, $type names, or invoke JSON unwrapping changed, also keep golem-skills/skills and tests under golem-skills/tests up to date.

External Process Ownership

Tests that directly execute external processes belong in the CLI integration test suite. This includes Golem binaries such as golem and golem-cli, and tools or compilers such as cargo, rustc, npm, npx, tsc, bun, sbt, scala-cli, and moon.

  • Unit tests and worker-executor tests must never spawn external processes.
  • Non-CLI integration tests must use golem-test-framework for process-backed dependencies and must not spawn additional processes directly.
  • CLI integration tests may spawn the processes required by the behavior they exercise.

Build generated code and test components before the test run rather than invoking their toolchains from a unit or worker-executor test.

Test Filtering Rules (test-r)

This project uses test-r which supports multiple filter arguments after --. Filters are OR-matched (a test runs if it matches any filter). Each filter is a substring match, not a regex.

Test names in test-r are module-qualified paths without the crate/binary name prefix. For example, --list shows golem_common::model::oplog::payload::tests::roundtrip_ipaddress or integration::plugins::oplog_processor, but the first segment (golem_common:: or integration::) is the crate/binary name and is not part of the filterable test name. The filterable name starts from the second segment.

# Run a single specific test by function name (substring match):
cargo test -p <crate> -- roundtrip_ipaddress --report-time

# Run a single specific test using module path (substring match, omit first segment):
cargo test -p <crate> -- payload::tests::roundtrip_ipaddress --report-time

# Run a single specific test with --exact (must use FULL module path, omitting first segment):
cargo test -p <crate> -- model::oplog::payload::tests::roundtrip_ipaddress --exact --report-time
# For integration tests where --list shows integration::plugins::oplog_processor:
cargo test -p integration-tests --test integration -- plugins::oplog_processor --exact --report-time

# Run multiple specific tests (filters go AFTER --, not before):
cargo test -p <crate> -- test_name_1 test_name_2 test_name_3 --report-time

# WRONG - do NOT include the first segment (crate/binary name) in filters:
# cargo test -p golem-common -- golem_common::model::oplog --report-time
# cargo test -p integration-tests --test integration -- integration::plugins::oplog_processor --report-time

# WRONG - --exact with just the function name (needs full module path minus first segment):
# cargo test -p <crate> -- roundtrip_ipaddress --exact --report-time

# WRONG - multiple filters before -- causes "unexpected argument" error:
# cargo test -p <crate> test1 test2 -- --report-time

# WRONG - regex patterns don't work (filters are substring matches, not regex):
# cargo test -p <crate> -- "test_a|test_b" --report-time
# cargo test -p <crate> -- "test_.*pattern" --report-time

Note: --list in test-r ignores filters and always lists all tests. Do not use --list to verify that filters are working. Instead, do a real run and check the filtered out count in the result line.

Debugging Test Failures

Use --nocapture when debugging tests:

cargo test -p <crate> -- <test> --nocapture

Always save test output to a file when running worker executor tests, integration tests, or CLI tests. These tests are slow and produce potentially thousands of lines of logs. Never pipe output directly to grep, head, tail, etc. — if you need to examine different parts of the output, you would have to re-run the entire slow test. Instead:

cargo test -p <crate> -- <test> --nocapture > tmp/test_output.txt 2>&1
# Then search/inspect the saved file as needed
rg -n "pattern" tmp/test_output.txt

Handling hanging tests: Load the debugging-hanging-tests skill for a step-by-step workflow.

Test Components

Worker executor tests, integration tests, and CLI integration tests can depend on built WASM artifacts in test-components/. Generated .wasm files are generally not checked into the repository, so compiling the test components used by the selected tests is a separate prerequisite step before running the tests. The checked-in concurrent-delivery-order and concurrent-runtime-events WASMs are intentional minimal-fixture exceptions.

Use this workflow:

  1. Identify which tagged PrecompiledComponent or test component files the selected tests require.
  2. Build those components first by following their AGENTS.md, or run cargo make build-test-components if a broad rebuild is simpler.
  3. Only then run the Rust test command.

Load the modifying-test-components skill for targeted rebuilds, or rebuild-all-test-components for a full rebuild.

Timeouts

Add a #[timeout] attribute for tests that should fail rather than hang:

use test_r::test;
use test_r::timeout;

#[test]
#[timeout("30s")]
async fn my_test() {
    // ...
}

Choose a timeout generous enough for normal execution but short enough to fail quickly when hung (30s–60s for most tests, up to 120s for complex integration tests).

Signals

GitHub stars
2k
Forks
212
Last commit
Sep 2026
Hacker News mentions
20
Advanced
Catalog kind
skill
Gateway key
testing-golemcloud
Source
github.com/golemcloud/golem