Project Brief — Performance Test Suite for an E-Commerce API

10 min read

This capstone project brings together every concept from the course into a single, production-grade test suite. You will build a complete K6 performance testing solution for ShopFast — a fictional e-commerce REST API — covering all four testing patterns, realistic data management, custom business metrics, quality gates, and CI/CD integration.

The system under test

ShopFast is a REST API that powers an online retail platform. The API has five functional areas:

Authentication — login with email/password, returns a JWT. Tokens expire after 24 hours.

Products — list all products (paginated), search by keyword, get product detail. High read volume: 70% of all traffic.

Cart — add items, view cart contents, update quantities, remove items. Stateful: each user has their own cart tied to their session.

Checkout — create an order from the current cart, process payment (simulated), return an order ID. The most complex flow: involves inventory reservation, payment processing, and order record creation.

User — view profile, list past orders, update preferences. Low volume but sensitive to latency.

For the capstone, use https://jsonplaceholder.typicode.com as a stand-in for the ShopFast API. Map the ShopFast operations to real endpoints: products → /posts, users → /users, carts → /todos, orders → POST /posts. The testing patterns and code structure are what matter — not the specific API responses.

Performance SLAs

Endpoint categoryp95 targetp99 targetError rate
Authentication< 300ms< 500ms< 0.01%
Product browsing< 500ms< 800ms< 0.1%
Cart operations< 400ms< 700ms< 0.1%
Checkout< 1000ms< 2000ms< 0.01%
User profile< 400ms< 700ms< 0.1%
Overall throughput> 200 RPS

These SLAs drive the threshold configuration. Checkout gets a lenient latency threshold (1000ms) because it involves payment processing. It gets a strict error threshold (0.01%) because a failed checkout is a direct revenue loss.

The full deliverables

ShopFast test suite
  • – smoke.js — 1 VU, 60s, every PR
  • – load.js — mixed workload, 30m
  • – stress.js — find breaking point
  • – spike.js — 10× surge
  • – soak.js — 4h stability
  • – SharedArray: 1000 simulated users
  • – SharedArray: 500 product IDs
  • – setup(): shared auth token
  • – Per-VU token pattern for multi-user scenarios
  • – SLA thresholds per endpoint category
  • – Custom metric: order_success_rate > 99%
  • – Custom metric: checkout_flow_ms p(95) < 3000
  • – abortOnFail on error rate > 10%
  • GitHub Actions: smoke on every PR –
  • GitHub Actions: load test on merge to main –
  • Scheduled: full suite nightly –
  • HTML report uploaded as artifact –

Project structure

Organise the project as you would any production code:

tests/
  smoke.js              # 1 VU sanity check
  load.js               # mixed workload load test
  stress.js             # breaking point test
  spike.js              # traffic surge test
  soak.js               # 4-hour stability test
lib/
  auth.js               # login helper, token management
  http-helpers.js       # tagged request wrappers
  metrics.js            # custom metric definitions
data/
  users.json            # 1000 simulated users
  products.json         # 500 product IDs and names
baselines/
  load-test-baseline.json   # committed baseline for regression detection
.github/
  workflows/
    performance.yml     # GitHub Actions workflow

Keep the lib/ helpers lean. Their job is to reduce boilerplate in test files, not to build a framework. Three files — auth, request helpers, metrics — is enough.

The load test workload model

The load test must reflect real ShopFast traffic patterns. Based on analytics from similar e-commerce platforms:

  • 60% — product browsing: list products, view product detail, search by keyword
  • 20% — cart activity: add to cart, view cart, update quantities
  • 10% — checkout: full cart-to-order flow with payment
  • 10% — account activity: view profile, order history

Model this with Math.random() in the default function and distinct tagged requests for each flow. Run with the standard load test stage pattern: 5-minute ramp to 100 VUs, 20-minute hold, 5-minute ramp down.

Custom business metrics

HTTP metrics tell you that /orders took 420ms. Custom metrics tell you that 98.7% of checkout flows succeeded. Both are needed for a complete picture:

  • orders_created (Counter): increments on every successful POST /orders with status 201
  • checkout_completion_rate (Rate): true for completed checkouts, false for failures — threshold at rate>0.99
  • checkout_flow_ms (Trend): end-to-end duration from cart add to order confirmation — threshold at p(95)<3000
  • cart_items_added (Counter): tracks cart add volume as a business throughput signal

These metrics appear in the HTML report and Grafana dashboard alongside standard K6 metrics.

Acceptance criteria

Your test suite is complete when:

  1. All five test scripts (smoke, load, stress, spike, soak) run without errors against the mock API
  2. All thresholds pass for the smoke and load tests under normal conditions
  3. The stress test output shows the VU count at which the system's error rate crosses 5%
  4. The spike test output shows whether the system recovers within 2 minutes of the load dropping
  5. handleSummary generates an HTML report in every test
  6. The GitHub Actions workflow runs the smoke test on every commit and blocks on failure
  7. The load test nightly job uploads the HTML report as an artifact

These acceptance criteria are the definition of done. Work through them in order — each one builds on the previous.

Before you start

Read through the project brief completely before writing any code. Sketch the project structure on paper or in a text file. Identify which lessons from the course map to each deliverable:

  • SharedArray data → Chapter 5, Lesson 2
  • Multiple scenarios for mixed workload → Chapter 5, Lesson 3
  • constant-arrival-rate executor for throughput testing → Chapter 5, Lesson 4
  • Custom metrics definitions → Chapter 3, Lesson 4
  • SLA thresholds with abortOnFail → Chapter 7, Lesson 2
  • handleSummary with HTML report → Chapter 6, Lesson 1
  • GitHub Actions workflow → Chapter 7, Lesson 1

The next lesson is a guided walkthrough. Try to implement each piece independently first — even a rough version — before reading the walkthrough. The struggle of independent implementation is where the learning happens.

// tip to track lessons you complete and pick up where you left off across devices.