Testing
@alienplatform/testing deploys your stack from inside a test suite, so a test can hit its endpoints, send it commands, and tear it down. It runs a real local deployment, built the same way as production.
npm install --save-dev @alienplatform/testing vitestThe package runs the alien CLI, so install it first (see Quickstart). Set ALIEN_CLI_PATH to use a specific binary.
Write a test
This test deploys the running example, asks the api Worker for an upload URL, and calls the search command:
import { type Deployment, deploy } from "@alienplatform/testing"
import { afterAll, beforeAll, describe, expect, it } from "vitest"
describe("acme-docs", () => {
let deployment: Deployment
beforeAll(async () => {
deployment = await deploy({
app: ".",
environmentVariables: [{ name: "ACME_API_URL", value: "http://localhost:3000" }],
})
}, 300_000)
afterAll(async () => {
await deployment?.destroy()
})Each test reaches the deployment the way your backend would:
it("returns an upload URL and answers searches", async () => {
const res = await fetch(`${deployment.url}/uploads`, {
method: "POST",
body: JSON.stringify({ name: "msa.pdf" }),
})
expect(res.ok).toBe(true)
const { results } = await deployment.invokeCommand<{ results: string[] }>(
"search",
{ prefix: "inbox/", limit: 10 },
{ target: "processor" },
)
expect(Array.isArray(results)).toBe(true)
})
})Run it with npx vitest run. The first build can take minutes, so give beforeAll a generous timeout.
What deploy does
deploy({ app }) runs alien dev on a free port with a status file, waits until the deployment is ready, and returns a Deployment:
| Member | Use |
|---|---|
url | The public endpoint URL, or undefined when no resource exposes one |
invokeCommand(name, params, { target }) | Sends a command. target picks the resource when several have commands enabled |
setExternalSecret(vault, key, value) | Writes a value into a vault, as an admin would in their secret store |
destroy() | Stops the session |
deploy() deletes the app's .alien/ folder before it starts, so every run begins from empty resources. Don't point it at a folder where you keep a local session you care about.
Options:
configpicks another stack file.environmentVariablespasses plain or secret variables, with optionaltargetResources.verboseprints the CLI output.
Test cloud behavior
Local resources behave like their cloud counterparts for your code, but not for cloud-specific limits and IAM. To check those, pass platform: "aws", "gcp", or "azure".
The package then builds the stack, creates a release, and deploys it through the Alien API, which needs ALIEN_API_KEY in the environment. Run these tests less often than local ones; they create real resources.
In CI
Local tests need no cloud credentials. A GitHub Actions job installs Bun and the CLI, then runs the suite:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: curl -fsSL https://alien.dev/install | INSTALL_DIR="$HOME/.local/bin" sh
- run: echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- run: npm ci
- run: npx vitest runNext
- Releases: ship what you tested
- Local development: the same deployment, run by hand
- Testing SDK reference