Docs
Testing

Saved trace bundles

Reference for the files produced by `acton test --save-test-trace` and reused by the Test UI

Pass --save-test-trace to acton test to write reusable JSON artifacts for offline inspection. The browser Test UI can read the same trace and contract files.

acton test --save-test-trace

When bundles are written

  • acton test --save-test-trace without a value writes to build/traces.
  • acton test --save-test-trace custom-traces writes to the explicit directory instead.
  • Relative trace paths are resolved from the project root, not from the current working directory.
  • Regular test runs do not create trace artifacts unless trace export is enabled.
  • Test UI also enables the default trace bundle directory when trace export is not configured explicitly, including when UI is enabled through [test].ui.

Directory layout

test-default-trace_trace.json
test-custom-trace-names_trace.json
simple.json
forwarder.json
receiver.json
  • Each executed test normally writes one <test-name>_trace.json file.
  • Contract metadata is stored once per output directory under contracts/<contract-name>.json, even when multiple tests reuse the same contract.
  • Filenames are derived only from the test name and contract name. If those names collide across files, later exports overwrite earlier artifacts in the same output directory.

Root trace file

Each <test-name>_trace.json file has this top-level structure:

{
  "name": "test-custom-trace-names",
  "pos": { "uri": "...", "row": 1, "column": 1 },
  "contracts": ["simple"],
  "wallets": { "<addr>": "deployer" },
  "traces": [
    {
      "name": "deploy-counter",
      "transactions": [
        {
          "lt": "123",
          "raw_transaction": "...",
          "parent_transaction": null,
          "child_transactions": ["124"],
          "vm_log_diff": "...",
          "executor_logs": "...",
          "executor_actions": [],
          "dest_contract_info": "simple"
        }
      ]
    }
  ]
}
  • name: the owning test name.
  • pos: source location of the test in the .test.tolk file.
  • contracts: contract names that can be resolved in the sibling contracts/ directory.
  • wallets: known-address map used to preserve local wallet names such as deployer or sender.
  • traces: logical transaction chains captured during the test.
  • skipped_traces_count: optional count of trace chains hidden from the saved bundle with hideTraceFromUi(). The field is omitted when the count is zero.

Trace chains

Each item in traces represents one logical message chain:

  • name: a custom chain name from txs.giveName(...), or a fallback such as Trace 1.
  • transactions: ordered transactions in that chain.
  • failed_messages: optional failed message attempts attached to the same logical chain.

To keep exported traces readable, name them explicitly:

val txs = net.send(deployer.address, deployMsg);
txs.giveName("deploy-counter");

That custom name appears in traces[].name and in the Test UI.

Skipping traces

Use SendResultList.hideTraceFromUi() when a transaction chain is useful for test setup but should not appear in saved trace bundles or the Test UI:

val setupTxs = net.send(deployer.address, setupMsg);
setupTxs.hideTraceFromUi();

val userTxs = net.send(deployer.address, userMsg);
userTxs.giveName("user-flow");

Hidden traces are omitted from traces[], while the exported root file records how many chains were skipped in skipped_traces_count. The transactions still run normally and remain available to the test code for assertions before they are hidden.

For accepted external messages, use ExternalSendResult.hideTraceFromUi(). If the external message was not accepted, this helper fails with the same external-error diagnostics as other ExternalSendResult helpers.

Transactions

Each transaction entry carries both raw and decoded debugging context:

  • lt: logical time of the transaction.
  • raw_transaction: original transaction BOC as base64.
  • parent_transaction and child_transactions: links that preserve chain structure.
  • shard_account_before and shard_account: serialized account state before and after execution.
  • vm_log_diff: VM log diff generated for that transaction.
  • executor_logs: raw executor log output.
  • executor_actions: parsed executor actions such as send attempts and reserve operations, including failure details when available.
  • actions: optional base64-encoded actions cell copied from the trace export. Runtime helpers may decode it later when needed.
  • dest_contract_info: contract name hint for lookup in contracts/<name>.json.

Contract files

Each contracts/<contract-name>.json file stores the metadata needed to decode and inspect transactions:

  • name: Acton contract name from [contracts], used as the stable lookup key.
  • display_name: configured [contracts.<name>].display-name, used only for presentation.
  • code_boc64: compiled contract code encoded as base64 BoC.
  • source_map: compiler source map used to connect VM/executor locations back to Tolk source.
  • abi: compiler ABI used to decode storage, message bodies, opcodes, and typed values.

This lets offline tooling and the Test UI map traces back to source locations and known message layouts.

Step-by-step execution

Trace export keeps logical chains intact even when execution is split into batches with testing.createTraceIterationCursor().

Running part of a chain with executeN() and then executeAllRemaining() merges those batches back into one exported trace when they share the same root transaction. Naming any batch with giveName(...) keeps that logical trace readable in the final JSON.

Last updated on

On this page