# Test before you deploy

What you can verify locally, what only a deployed run can show, and how to use a sandbox tenant as your test bed.

There is no local platform mode: the runtime, the gateway, the connectors, and the policy
checkpoints exist only in a tenant. Testing is therefore two layers: what you can check on your
machine in seconds, and what you check with a real run in the sandbox tenant.

- **Locally:** the contract test, your own unit tests, and `tanomis agent deploy --dry-run`.
- **In the sandbox tenant:** `tanomis session run` and runs from your application, with the real
  gateway, connectors, and approvals.
- **Before customers:** the evaluation gate and a canary.

## Locally, in seconds

```bash title="Terminal"
cd agents/support-copilot
uv run python -m unittest tests/test_agent_contract.py
tanomis agent deploy . --tenant "$TANOMIS_TENANT" --dry-run
```

The generated contract test imports your module and checks the entrypoint's shape. Add your own
tests beside it for prompt construction, tool functions, and input validation; your entrypoint is
plain Python and imports without the runtime.

The dry run validates the manifest, the lock policy, and the packaged inputs against the tenant's
ceilings, uploads nothing, and ends with "no changes made". Run it on every pull request; see
[Deploy from CI](/guides/deploy/deploy-from-ci).

What a local test cannot show: model behaviour, connector calls, approvals, egress refusals,
session state. Those need a tenant.

## In the sandbox tenant

Deploy to the sandbox tenant, which serves no customer, and run the agent the way your
application will:

```bash title="Terminal"
tanomis agent deploy . --tenant northwind-sandbox
tanomis session run support-copilot --tenant northwind-sandbox \
  --prompt "Customer reports that CSV exports stop at 80%. Draft a first response."
```

Then exercise the edges: a prompt that should trigger an approval, a tool call outside the
connector allowlist, a host outside `network.egress`. Each refusal shows up in the run's events
and in the audit trail, which is the behaviour you are testing.

For application-side flows, point your integration at the sandbox tenant's workspace and
follow [Invoke from your application](/guides/run/invoke-from-your-application); the API is the
same in every tenant.

## Before customers

Score the candidate against the version you trust with [Evaluate a version](/guides/evaluate/evaluate-a-version),
then canary it for one or two customers with [Roll out and roll back](/guides/deploy/rollout-and-rollback).
A version that passed in the sandbox is the same immutable build that reaches customers; only
each tenant's policy differs.

## Where to go next

- [Environments and contexts](/guides/deploy/environments-and-contexts): the sandbox beside your
  customers.
- [Session workspace and state](/guides/build/session-workspace-and-state)
