Skip to content

Commit edbb690

Browse files
oleiadeankur22
authored andcommitted
docs: add assertions documentation page
1 parent 7f4543e commit edbb690

File tree

1 file changed

+346
-0
lines changed

1 file changed

+346
-0
lines changed
Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
---
2+
title: 'Assertions'
3+
description: 'Advanced test assertions in k6 using the k6-testing library for both protocol and browser testing'
4+
weight: 04
5+
---
6+
7+
{{< docs/shared source="k6" lookup="preview-feature.md" version="<K6_VERSION>" >}}
8+
9+
# Assertions
10+
11+
k6 provides test assertions in the form of the `expect` function. Assertions validate that your application behaves as expected during testing.
12+
13+
Define assertions by passing a value to `expect()` and chaining it with a matcher that defines your expected outcome. The library provides expressive matchers that work with both protocol testing (HTTP/API) and browser testing scenarios.
14+
15+
The assertions API is compatible with Playwright's assertion syntax, providing a fluent interface that improves test readability and reliability.
16+
17+
## Getting started
18+
19+
Assertions are provided by the [k6-testing library](https://jslib.k6.io). Import the library to start using assertions:
20+
21+
```javascript
22+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
23+
import { browser } from "k6/browser";
24+
import http from "k6/http";
25+
26+
export function protocolTest() {
27+
// Get the home page of k6's Quick Pizza app
28+
const response = http.get("https://quickpizza.grafana.com/");
29+
30+
// Simple assertions
31+
expect(response.status).toBe(200);
32+
expect(response.error).toEqual("");
33+
expect(response.body).toBeDefined();
34+
}
35+
36+
export async function browserTest() {
37+
const page = await browser.newPage();
38+
39+
try {
40+
await page.goto("https://quickpizza.grafana.com/");
41+
await page.waitForLoadState("networkidle"); // waits until the `networkidle` event
42+
43+
// Assert the "Pizza Please" button is visible
44+
await expect(page.locator("button[name=pizza-please]")).toBeVisible();
45+
} finally {
46+
await page.close();
47+
}
48+
}
49+
50+
export const options = {
51+
scenarios: {
52+
// Protocol tests
53+
protocol: {
54+
executor: "shared-iterations",
55+
vus: 1,
56+
iterations: 1,
57+
exec: "protocolTest",
58+
},
59+
60+
// Browser tests
61+
ui: {
62+
executor: "shared-iterations",
63+
options: {
64+
browser: {
65+
type: "chromium",
66+
},
67+
},
68+
exec: "browserTest",
69+
},
70+
},
71+
};
72+
```
73+
74+
## Types of assertions
75+
76+
The k6-testing library provides two types of assertions, each designed for different testing scenarios:
77+
78+
### Non-retrying assertions
79+
80+
[Non-retrying assertions](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/testing/non-retrying-assertions) evaluate conditions immediately at a single point in time without retrying. They're ideal for validating static data such as HTTP response content, data structures, or configuration values.
81+
82+
```javascript
83+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
84+
import http from 'k6/http';
85+
86+
export default function () {
87+
const pizzaRequestPayload = { maxCaloriesPerSlice: 1000, mustBeVegetarian: true };
88+
const pizzaRequestHeader = {
89+
"Content-Type": "application/json",
90+
"Authorization": "Token " + "abcdef0123456789"
91+
}
92+
93+
const response = http.post(
94+
`https://quickpizza.grafana.com/api/pizza`,
95+
JSON.stringify(pizzaRequestPayload),
96+
{ headers: pizzaRequestHeader }
97+
);
98+
const data = response.json();
99+
100+
// These assertions evaluate immediately
101+
expect(response.status).toEqual(200);
102+
expect(response.headers["Content-Type"]).toBeDefined();
103+
expect(response.headers["Content-Type"]).toEqual("application/json");
104+
expect(data.pizza).toBeDefined();
105+
expect(data.pizza.name).toBeDefined();
106+
expect(data.pizza.name).not.toHaveLength(0);
107+
}
108+
```
109+
110+
### Auto-retrying assertions
111+
112+
[Auto-retrying assertions](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/testing/retrying-assertions) automatically retry until conditions become true or a timeout is reached. They're designed for browser testing scenarios where elements may take time to load, update, or become interactable.
113+
114+
```javascript
115+
import { expect } from 'https://jslib.k6.io/k6-testing/0.5.0/index.js';
116+
import { browser } from 'k6/browser';
117+
118+
export default async function() {
119+
// Open a new browser page
120+
const page = await browser.newPage()
121+
122+
try {
123+
// Navigate to the quickpizza website
124+
await page.goto('https://quickpizza.grafana.com/')
125+
126+
// Click the 'Pizza please' button
127+
await page.locator('button[name="pizza-please"]').click()
128+
129+
// Take a screenshot of the homepage, and save it to the local filesystem
130+
// so we can inspect it later if needed.
131+
await page.screenshot({ path: 'homepage.png' })
132+
133+
// Check if the pizza recipe is displayed
134+
const textContent = await pizzaRecipeIsDisplayed(page)
135+
expect(textContent).toEqual('Our recommendation:')
136+
} finally {
137+
await page.close()
138+
}
139+
}
140+
141+
// Browsers are asynchronous, so we need to wait for the content we want to check
142+
// to be visible.
143+
async function pizzaRecipeIsDisplayed(page) {
144+
const label = await page.locator('h2[id="pizza-name"]')
145+
await label.isVisible()
146+
const textContent = (await label.textContent()).trim()
147+
148+
return textContent
149+
}
150+
```
151+
152+
## Assertions vs. checks
153+
154+
Unlike k6 [checks](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/checks), which continue execution when they fail and register metrics for threshold evaluation, assertions immediately fail and interrupt the test when expectations are not met. Assertions are designed for validating critical conditions that determine whether a test should continue—when these conditions aren't met, they invalidate the entire testing scenario.
155+
156+
Assertions do not register metrics because they halt execution rather than collect data points. This design provides fast feedback and detailed error messages to help you identify issues quickly, ensuring your tests only proceed when fundamental assumptions are satisfied.
157+
158+
## Available assertion methods
159+
160+
### Non-retrying assertions
161+
162+
Use these for immediate evaluation of static values:
163+
164+
| Method | Description |
165+
| --- | --- |
166+
| [toBe()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobe) | Exact equality using Object.is() |
167+
| [toEqual()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/toequal) | Deep equality comparison |
168+
| [toBeTruthy()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobetruthy) | Value is truthy |
169+
| [toBeFalsy()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobefalsy) | Value is falsy |
170+
| [toBeDefined()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobedefined) | Value is not undefined |
171+
| [toBeUndefined()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobeundefined) | Value is undefined |
172+
| [toBeNull()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobenull) | Value is null |
173+
| [toBeGreaterThan()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobegreaterthan) | Numeric greater than |
174+
| [toBeGreaterThanOrEqual()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobegreaterthanorequal) | Numeric greater than or equal |
175+
| [toBeLessThan()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobelessthan) | Numeric less than |
176+
| [toBeLessThanOrEqual()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobelessthanorequal) | Numeric less than or equal |
177+
| [toBeCloseTo()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobecloseto) | Floating point comparison |
178+
| [toContain()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tocontain) | Array/string contains value |
179+
| [toContainEqual()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tocontainequal) | Array contains object with matching content |
180+
| [toHaveLength()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tohavelength) | Array/string has specific length |
181+
| [toHaveProperty()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tohaveproperty) | Object has specific property |
182+
| [toBeInstanceOf()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/non-retrying-assertions/tobeinstanceof) | Value is instance of class |
183+
184+
[See all non-retrying assertions →](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/testing/non-retrying-assertions)
185+
186+
### Auto-retrying assertions
187+
188+
Essential for browser testing with dynamic content:
189+
190+
| Method | Description |
191+
| --- | --- |
192+
| [toBeVisible()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tobevisible) | Element is visible on the page |
193+
| [toBeHidden()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tobehidden) | Element is hidden or not visible |
194+
| [toBeEnabled()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tobeenabled) | Element is enabled and interactive |
195+
| [toBeDisabled()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tobedisabled) | Element is disabled |
196+
| [toBeChecked()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tobechecked) | Checkbox or radio button is checked |
197+
| [toBeEditable()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tobeeditable) | Element is editable |
198+
| [toHaveText()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tohavetext) | Element has specific text content |
199+
| [toContainText()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tocontaintext) | Element contains specific text |
200+
| [toHaveValue()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tohavevalue) | Input element has specific value |
201+
| [toHaveAttribute()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6-testing/retrying-assertions/tohaveattribute) | Element has specific attribute value |
202+
203+
[See all retrying assertions →](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/testing/retrying-assertions)
204+
205+
## Assertion features
206+
207+
### Negation
208+
209+
All assertions can be negated using `.not`:
210+
211+
```javascript
212+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
213+
import http from 'k6/http';
214+
215+
export default function () {
216+
const response = http.get('https://quickpizza.grafana.com/');
217+
218+
// Negated assertions
219+
expect(response.status).not.toBe(404);
220+
expect(response.body).not.toHaveLength(0);
221+
expect(response.headers).not.toHaveProperty('error');
222+
223+
// Browser negation (with await)
224+
await expect(page.locator('.error-message')).not.toBeVisible();
225+
}
226+
```
227+
228+
### Soft assertions
229+
230+
Soft assertions continue test execution even when they fail, marking the test as failed but allowing subsequent assertions to run:
231+
232+
```javascript
233+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
234+
import http from 'k6/http';
235+
236+
export default function () {
237+
const response = http.get('https://quickpizza.grafana.com/');
238+
239+
// These will all run even if some fail
240+
expect.soft(response.status).toBe(200);
241+
expect.soft(response.headers['Content-Type']).toContain('text/html');
242+
expect.soft(response.body).toHaveLength(response.body.length);
243+
244+
// Test continues and performs additional checks
245+
console.log('Test completed, checking results...');
246+
}
247+
```
248+
249+
### Custom error messages
250+
251+
Provide descriptive error messages for better debugging:
252+
253+
```javascript
254+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
255+
import http from 'k6/http';
256+
257+
export default function () {
258+
const response = http.get('https://quickpizza.grafana.com/api/pizza', {
259+
headers: { 'Content-Type': 'application/json' }
260+
});
261+
const pizza = response.json();
262+
263+
expect(response.status, 'API should return successful response').toBe(200);
264+
expect(pizza.name, 'Pizza should have a valid name').toBeDefined();
265+
expect(pizza.name, 'Pizza name should not be empty').not.toHaveLength(0);
266+
}
267+
```
268+
269+
## Configuration and customization
270+
271+
### Global configuration
272+
273+
Configure assertion behavior globally for all tests:
274+
275+
```javascript
276+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
277+
import http from 'k6/http';
278+
279+
// Configure global settings
280+
const configuredExpect = expect.configure({
281+
timeout: 10000, // 10 seconds for retrying assertions
282+
interval: 500, // Check every 500ms
283+
colorize: true, // Enable colored output
284+
softMode: 'fail' // How soft assertions behave
285+
});
286+
287+
export default function () {
288+
const response = http.get("https://quickpizza.grafana.com");
289+
290+
// All assertions use these settings
291+
configuredExpect(response.status).toBe(200);
292+
}
293+
```
294+
295+
### Per-scenario configuration
296+
297+
Create different configurations for different test scenarios:
298+
299+
```javascript
300+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
301+
import http from 'k6/http';
302+
import { browser } from 'k6/browser';
303+
304+
// Fast assertions for API testing
305+
const fastExpect = expect.configure({
306+
timeout: 2000,
307+
interval: 100
308+
});
309+
310+
// Slow assertions for complex browser interactions
311+
const slowExpect = expect.configure({
312+
timeout: 30000,
313+
interval: 1000,
314+
softMode: 'continue'
315+
});
316+
317+
export default async function () {
318+
// Use appropriate expectation based on test type
319+
const response = http.get('https://quickpizza.grafana.com/');
320+
fastExpect(response.status).toBe(200);
321+
322+
if (__ENV.BROWSER_TEST) {
323+
const page = await browser.newPage();
324+
await page.goto('https://quickpizza.grafana.com/');
325+
await slowExpect(page.locator('h1')).toBeVisible();
326+
}
327+
}
328+
```
329+
330+
## Best practices
331+
332+
For tests that primarily use assertions to validate system state, such as tests verifying a successful deployment in CI pipelines, run k6 tests with assertions in quiet mode:
333+
334+
```bash
335+
k6 run --quiet --no-summary script.ts
336+
```
337+
338+
This approach eliminates unnecessary output and focuses on the assertion results, making it ideal for automated testing environments.
339+
340+
## See also
341+
342+
- [expect() API reference](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/testing/expect) - Complete assertion documentation
343+
- [Auto-retrying assertions](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/testing/retrying-assertions)
344+
- [Non-retrying assertions](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/testing/non-retrying-assertions)
345+
- [Browser testing](https://grafana.com/docs/k6/<K6_VERSION>/using-k6-browser) - Browser automation with k6
346+
- [Checks](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/checks) - Alternative validation approach

0 commit comments

Comments
 (0)