Skip to main content
Use a separate test for each boundary your integration crosses. A local engine test, an authenticated HTTP request, and a completed provider operation establish different things. This guide helps you choose the assertions and includes a complete payment-replay test that runs across two Node processes.

Start with the behavior you need to prove

Start with the integration test suite and error-handling tests. They cover stock reservation, rejection without partial writes, cancellation, payment replay, and unexpected-error propagation. Those tests need no hosted credentials.

Test replay after a process restart

An in-process replay test can miss accidental dependence on application memory. This program starts one process to create a payment, waits for it to exit, and starts another to replay the original input against the same database. Each test run gets a new temporary directory. Use Node.js 20.20.0+, npm 10+, and @stateset/embedded 1.35.1:
Save this as restart.test.mjs:
Run from the project directory where you installed the package:
Success: 1 test passes, the process exits with status 0, and the temporary database is removed. The subprocesses inherit the working directory so they can resolve the installed package. A worker error or timeout fails the test rather than being treated as an empty result. This verifies a clean process restart using a persisted database and the original key and payload. It does not test an interrupted transaction, concurrent writers, disk failure, or an external charge. The payment intentionally remains pending. The key is fixed because every run uses a fresh database. In an application, persist one key per intended operation along with its original request; do not reuse this teaching key for unrelated payments. See payment and refund behavior.

Add hosted API checks as a separate layer

Select the service from the API directory. Record its host, authentication header, key scope, and test workspace. There is no universal StateSet sandbox host or shared test key for all engines. For ResponseCX, the developer guide’s first request reads the workspace with agents:read. Assert the response fields described by the workspace contract; do not hardcode the agent count of a shared workspace. For a write check, follow the ResponseCX quickstart: create an inactive agent, save its returned ID, then read it back and compare its configuration. Agent creation, activation, and a customer-channel interaction are separate checks. A 201 response alone does not establish that an agent can answer a customer correctly. A test that requires a key must report a missing credential clearly. If your normal suite intentionally skips hosted checks, report them as skipped and run the selected hosted job before claiming that integration was verified.

Verify asynchronous outcomes

Use the start operation’s returned ID to correlate later reads and events. An accepted start request proves acceptance, not completion. Define a deadline and inspect the workflow’s actual state until it reaches the expected terminal state or the deadline expires. For each workflow, write down:
  1. The accepted starting state and the operation ID returned by the service.
  2. The completion or failure states named by that service’s contract.
  3. The database records or provider results that must exist after completion.
  4. The outcome of a repeated request or duplicate event.
  5. The cleanup or reconciliation needed when only part of the workflow finishes.
The Temporal walkthrough shows start and status requests for that engine. The error-handling guide explains why a timeout requires reconciliation before repeating a write.

Expand failure coverage intentionally

Use a test double to trigger a lost response in your own adapter, but label that coverage as application behavior. It does not establish a remote service’s deduplication or delivery semantics. Verify those against the service separately.

Measure performance after correctness

Choose the exact operation, dataset size, concurrency, and environment before comparing runs. Measure failures as well as successful requests. Report failed attempts divided by all attempts; dividing by successful requests gives the wrong error rate. Include latency percentiles, throughput, timeout count, and failure count. Keep expected business rejections separate from infrastructure failures so a workload dominated by out-of-stock requests does not look like successful order creation. A local SQLite result does not establish hosted API capacity. Use the intended service’s contract and an agreed test environment for remote load tests; the Sandbox API provides isolated runtimes, not a generic commerce /orders endpoint.

Keep CI results interpretable

Run local tests without service credentials on each change. The integration-testing guide provides a complete CI job. Add node --test restart.test.mjs to that job after saving the program above and committing your package lockfile. Keep hosted and provider checks in separately named jobs with their own configuration. When a job fails, retain its runtime/package version, operation name, assertion, and redacted correlation IDs. Report cleanup failures separately so they do not hide the original failure. Do not rerun an entire write workflow automatically to make a failed build green.

Next steps

Last modified on September 20, 2026