Skip to content
Back to skills

Write Performance Test

ASecurity

Use when adding a new k6 performance test to this Vexa repo — load/stress/spike/soak/smoke testing an endpoint using the app's already-authenticated session. Triggers include "write a performance test for X", "load test this endpoint", "add a k6 script for X", "stress test the app", "how many users can this endpoint handle".

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
testingshellbashtestingapiperformance

Works with

  • api

Security analysis

A100/100

Scanned September 24, 2026

npx -y skills add rohitmann721994/vexa --skill write-performance-test --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Write Performance Test?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Write Performance Test
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rohitmann721994-write-performance-test/badge)](https://www.skillsdirectory.com/skills/rohitmann721994-write-performance-test)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: write-performance-test
description: Use when adding a new k6 performance test to this Vexa repo — load/stress/spike/soak/smoke testing an endpoint using the app's already-authenticated session. Triggers include "write a performance test for X", "load test this endpoint", "add a k6 script for X", "stress test the app", "how many users can this endpoint handle".
---

# Write a Performance Test

## Overview

Scaffold a new k6 script the way this framework expects: under `k6/scripts/`
or `k6/scenarios/`, reusing the same session cookie `ApiLibrary` already
captures (`k6/utils/auth.js`), with thresholds defined upfront and a report
written to `reports/` in the same self-contained-HTML style as the pytest
suite. Read `docs/performance-testing-guide.md` first for the full reference
(test types, thresholds, report format); read the vendored `k6-performance`
skill for generic k6 syntax (executors, custom metrics, data-driven tests).

**k6 is a separate toolchain.** It is not installed by `uv sync` and does not
run through `pytest` — it needs the k6 binary installed separately and is
invoked directly with `k6 run`.

## Why auth works differently here

The app is an SPA + SSO with no server-side login form (see CLAUDE.md's
"Authentication flow" section) — the same reason `ApiLibrary` exists for the
`tests/api/` suite. k6 has no browser, so it **cannot** log in on its own; it
replays the raw `Cookie` header `ApiLibrary` already captured into
`API_COOKIES` in `.env`. Never write a k6 script that tries to POST credentials
to a login endpoint directly — that's not how this app authenticates.

## Steps

Track these as todos; do them in order.

### 1. Pick the test type

| Type | Question it answers | Script |
|------|---------------------|--------|
| Smoke | Does it work at all, at minimal load? | `k6/scripts/smoke-test.js` |
| Load | Does it meet its SLA at expected steady-state traffic? | `k6/scripts/load-test.js` |
| Stress | Where's the breaking point, and how does it degrade? | `k6/scripts/stress-test.js` |
| Spike | Does it survive a sudden burst, and recover? | `k6/scripts/spike-test.js` |
| Soak | Does anything degrade over hours (leaks, exhaustion)? | `k6/scripts/soak-test.js` |

Always run smoke first — if it fails, load/stress/spike/soak will fail for
the same reason at much higher cost.

### 2. Confirm the endpoint

Same discipline as `write-api-test`: hit the endpoint in the browser or via
`tests/api/` while logged in. Note the path, expected status, and whether it
needs query params or a specific role.

### 3. Make sure auth is available

```bash
uv run pytest tests/api/test_example_api.py -m api   # mints/refreshes API_COOKIES
```

Then export `API_BASE_URL` and `API_COOKIES` from `.env` into the shell (k6
reads `__ENV`, not `.env` files — see `docs/performance-testing-guide.md` for
the exact one-liners for bash and PowerShell).

### 4. Write or extend the script

For a single endpoint, copy the relevant `k6/scripts/*.js` and change the
request. For multiple endpoints in one run, copy `k6/scenarios/api-scenarios.js`
and add one `exec` function per flow. Always:

- Import `BASE_URL` from `k6/config/environments.js` and `authHeaders()` from
  `k6/utils/auth.js` — never hardcode the URL or rebuild the cookie by hand.
- Define `thresholds` (import from `k6/thresholds/default-thresholds.js` or
  set tighter ones for a specific SLA) — a script with no thresholds is just
  an observation, not a test.
- `check()` the response status/shape, not just that a request completed.
- Export `handleSummary` calling `handleSummaryReport('<name>', data)` from
  `k6/utils/report.js` so the run produces the standard HTML+JSON report.

### 5. Run it

```bash
k6 run k6/scripts/<name>-test.js
```

Reports land at `reports/k6_<name>_<timestamp>.html` (open in a browser) and
`.json` (raw metrics). Report the actual thresholds pass/fail k6 prints —
never claim a passing run you didn't see.

## Common Mistakes

- Trying to `http.post` a login/credentials request — this app can't
  authenticate that way; reuse `authHeaders()` instead.
- No thresholds, or thresholds copy-pasted without adjusting for the
  endpoint's real SLA.
- No think time (`sleep()`) between requests — instant hammering isn't a
  realistic traffic pattern.
- Running stress/spike/soak against a shared staging/prod environment without
  telling the team first (see the k6-performance skill's anti-patterns list).
- Forgetting `handleSummary` — without it, the run doesn't produce the
  standard `reports/` output the rest of the suite uses.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.