---
kind: guide
zz: "0.4.0"
updated: 2026-10-07
state: draft
rules: https://zriz.io/llms.txt
---
# Write your first zriz test

Add one HTTP call of your own service to the project, write one pipeline with one check, and run it. The work is done when the run has status `pass`.

The sample `hello` showed that the project works. This test is your own: one [pipeline](https://zriz.io/docs/words.md#pipeline) that calls one path of your service.

The page [Pipelines](https://zriz.io/docs/pipelines.md) gives the full format. `zz guide` prints the same text.

## Before you start {#before-you-start}

- `zz` is installed: `zz version`
- The current folder has a project, and the sample passes: `zz run hello`

## 1. Add the call to the resource {#add-the-call}

### Do

Open `.zriz/resources/target.json`. `zz init` wrote it. Add one action to `actions`, and keep the action `check` as it is.

- `<health path>` is the path that the file has now.
- `<action>` is a name that you give to the call. Example: `list-orders`.
- `<path>` is a path of your service that answers status 200 to a GET.

`.zriz/resources/target.json`:

```json
{
  "type": "http",
  "description": "Your app under test",
  "base-url": "${env.TARGET_URL}",
  "actions": {
    "check": { "method": "GET", "path": "<health path>" },
    "<action>": { "method": "GET", "path": "<path>" }
  }
}
```

```sh
zz validate hello
```

### Why

A [step](https://zriz.io/docs/words.md#step) can call only an action that a [resource](https://zriz.io/docs/words.md#resource) file names. The base URL comes from `TARGET_URL` in `.zriz/environments/local.json`.

### You should see

```text
{"ok":true,"command":"validate",
```

### If not

- `"ok":false`: The file is not correct. `error.file` and `error.message` name the fault. Correct it, then do the command again.
- `not a zriz project`: Go to the folder of your service. Then do the command again.

## 2. Write the pipeline {#write-the-pipeline}

### Do

Make a new file in `.zriz/pipelines`. The name of the file is the name of the pipeline.

- `<pipeline>` is a name that you give to the test. Use letters, digits, and `-`. Example: `list-orders`.
- `<description>` is one line that says what the test shows.
- `<action>` is the name from step 1.

`.zriz/pipelines/<pipeline>.json`:

```json
{
  "description": "<description>",
  "steps": [
    { "call": "target/<action>", "expect": [["status", "==", 200]] }
  ]
}
```

```sh
zz validate <pipeline>
```

### Why

The pipeline has one step and one [check](https://zriz.io/docs/words.md#check). The check passes when your service answers status 200.

### You should see

```text
{"ok":true,"command":"validate",
```

### If not

- `missing-action`: The `call` names an action that `target.json` does not have. `error.valid` lists the actions. Correct the name.
- `no pipeline`: The file name and the name in the command are not the same. Correct one of them.
- `"ok":false`: `error.file` and `error.message` name the fault. Correct it, then do the command again.

## 3. Run the test {#run-the-test}

### Do

Start your service. `<pipeline>` is the name from step 2.

```sh
zz run <pipeline>
```

### Why

`zz validate` checks the files only. A [run](https://zriz.io/docs/words.md#run) makes the call and does the check.

### You should see

```text
"status":"pass"
```

### If not

- `"status":"fail"`: The check did not pass. Do the command in `hints` of the reply. It shows the failed step and the status that your service gave.
- `not logged in`: Do `zz login`. The [quick start](https://zriz.io/docs.md#log-in) gives the step.
- `too-many-runs`: The org is at the limit of the free tier. Read [What happens at the limit?](https://zriz.io/docs/limits.md#at-the-limit)

## Next {#next}

- Add a check on the body, a second step, or a database query. The page [Pipelines](https://zriz.io/docs/pipelines.md) gives each part.
- Keep secrets out of resource files. The page [Security](https://zriz.io/docs/security.md#database-password) tells why.
