Tutorial: Build Your First Test
In this tutorial, you will write a complete Gherkio declarative integration test scenario from scratch.
We will build a multi-step user journey mimicking a content platform workflow:
- Fetch a post from an API endpoint.
- Assert the response status, check that the title is a non-empty string, and verify the post ID is correct.
- Save the
userIdfrom the post response. - Fetch the user's profile using the saved variable and assert their username matches.
🛠️ Step 1: Create Your Test File
First, navigate to your Gherkio test directory (created during gherkio init) and create a new YAML file:
touch .gherkio/tests/example/auth/my-first-test.yaml
```text
Open this file in your favorite text editor.
---
## 📝 Step 2: Define Scenario Metadata
Every Gherkio test suite begins with a scenario declaration and optional tag lists for easy test suite filtering:
```yaml
scenario: Fetch Post and Verify Author Profile
tags:
- regression
- tutorial
```text
---
## 🔄 Step 3: Write the First Step (Fetch & Assert)
Let's append our first test step under the `steps` list. This step issues a standard HTTP `GET` request to fetch Post `#1`:
```yaml
steps:
- request:
method: GET
url: https://jsonplaceholder.typicode.com/posts/1
expect:
status: 200
body.id: 1
body.title: string
body.userId: integer
```text
### 💡 What's Happening Here?
- **`request.method` & `request.url`**: Define the HTTP command and fully-qualified target path.
- **`expect.status: 200`**: Ensures the server replies with a `200 OK` status.
- **`expect.body.id: 1`**: Asserts exact equality. The post ID must be exactly `1`.
- **`expect.body.title: string`**: Evaluates the data type. Asserts that the title field returned is a string.
- **`expect.body.userId: integer`**: Ensures the author reference is a valid number.
---
## 💾 Step 4: Extract and Save Context Variables
Before fetching the user's profile, we need to know who wrote Post #1. We can extract the `userId` field dynamically and save it under a temporary variable name:
```yaml
save:
authorId: body.userId
```text
### 💡 What's Happening Here?
- **`save`**: The context extractor block.
- **`authorId: body.userId`**: Resolves the JSON body field `userId` (e.g. `1`), and binds its value to the session variable `authorId` for subsequent steps.
---
## 🔗 Step 5: Write the Second Step (Variable Reuse)
Now, let's add a second step to retrieve the profile of the author we just saved. We will interpolate the `$authorId` variable directly in the request URL:
```yaml
- request:
method: GET
url: https://jsonplaceholder.typicode.com/users/$authorId
expect:
status: 200
body.id: integer
body.username: string
```text
### 💡 What's Happening Here?
- **`url: .../users/$authorId`**: Gherkio automatically replaces `$authorId` with the value extracted in the previous step (e.g. `https://jsonplaceholder.typicode.com/users/1`).
- **`expect.body.username: string`**: Confirms that the profile contains a valid, non-empty username.
---
## 🚀 Step 6: Review the Full Scenario File
Here is what your completed `.gherkio/tests/example/auth/my-first-test.yaml` file should look like:
```yaml
scenario: Fetch Post and Verify Author Profile
tags:
- regression
- tutorial
steps:
- request:
method: GET
url: https://jsonplaceholder.typicode.com/posts/1
expect:
status: 200
body.id: 1
body.title: string
body.userId: integer
save:
authorId: body.userId
- request:
method: GET
url: https://jsonplaceholder.typicode.com/users/$authorId
expect:
status: 200
body.id: integer
body.username: string
```text
---
## 🏃 Step 7: Run Your Test
Now run your new declarative scenario using the Gherkio CLI:
```bash
gherkio run example/auth/my-first-test.yaml --verbose
```text
### 🎉 The Output
Gherkio will execute both steps sequentially, resolving variables on the fly, and outputting beautiful execution metrics:
```text
✔ Step 1: GET https://jsonplaceholder.typicode.com/posts/1 [200 OK] (95ms)
✔ Assertion: status == 200
✔ Assertion: body.id == 1
✔ Assertion: body.title matches type string
✔ Assertion: body.userId matches type integer
→ Saved authorId: 1
✔ Step 2: GET https://jsonplaceholder.typicode.com/users/1 [200 OK] (87ms)
✔ Assertion: status == 200
✔ Assertion: body.id matches type integer
✔ Assertion: body.username matches type string
=======================================================
SCENARIO RESULT: PASSED
Total Steps: 2 | Passed: 2 | Failed: 0 | Duration: 182ms
=======================================================
```text
You've successfully built, written, and verified your first multi-step integration test flow! Next, check out how to structure your custom local environment files to avoid hardcoding domain URLs under **[Folder & Project Setup](project-setup.md)**.