Build a load test
A load test is only as good as its data: one hard-coded user posted a thousand times hits caches and unique constraints, not your real code paths. A test bundle generates the data and the test script together.
1. Describe the data and the requests
version: "1"
output:
language: eng
format: json # k6 reads JSON data
package: k6
quantity: 500 # one record per iteration
scenario:
baseURL: "${BASE_URL}"
load:
virtualUsers: 20
durationSeconds: 60
requests:
- name: sign-up
method: POST
path: /api/users
headers: { Content-Type: application/json }
body:
name: "{{name}}"
email: "{{email}}"
password: "{{password}}"
expect: { status: [201] }
- name: read-profile
method: GET
path: /api/users/by-email/{{email}}
expect: { status: [200] }
fields:
- { name: name, type: text, category: fullName }
- { name: email, type: email, unique: true }
- { name: password, type: password, length: 16 }fieldsdescribe one user.unique: truekeeps the sign-ups from colliding.scenario.requestsrun in order for each record: sign up, then read the profile back.{{email}}in the path or body is replaced with the record's value.baseURLis a placeholder, so the same bundle runs against any environment.
2. Generate the bundle
Generate the recipe as usual — in the app or with POST /api/v1/generate. The download is a ZIP:
test.js # the k6 script
data.json # 500 generated users
README.md # how to run it3. Run it
unzip ghostbakery-output.zip -d signup-load && cd signup-load
BASE_URL=https://staging.example.com k6 run test.jsEach iteration takes the next record from data.json, runs both requests and checks their status codes. k6 prints the check results and latencies at the end.
Other tools
Change output.package — and output.format where the tool needs it — and generate again. The scenario stays the same.
package |
Tool | Requires | Scenario file | Data file | Status assertions |
|---|---|---|---|---|---|
k6 |
JavaScript load-test script for Grafana k6. | format: json |
test.js |
data.json |
yes |
artillery |
YAML load-test script with a CSV payload. | format: csv |
test.yaml |
data.csv |
— |
jmeter |
JMX test plan with a CSV data set. | format: csv |
test-plan.jmx |
data.csv |
— |
postman |
Postman Collection for the collection runner. | format: json |
collection.json |
data.json |
yes |
hurl |
Hurl file for CI and end-to-end checks. | format: json |
requests.hurl |
data.json |
yes |
http |
.http request file for IDE HTTP clients. |
format: json |
requests.http |
data.json |
— |
k6, Postman and Hurl check expect.status; Artillery, JMeter and .http files carry the requests without assertions. Load settings are translated where the tool has an equivalent. See the test bundle reference for every key.
Tips
- Size the data to the run. With fewer records than iterations, records are reused; with
uniquekeys that means conflicts on the second pass. Generate at least as many records as the test runs iterations. - Point at a test environment. A load test against production is an incident. Use a staging
BASE_URL. - Keep secrets out of the recipe. Put tokens in environment variables your tool reads, not in
headers.