Performance test for the ShopLite e-commerce API, implemented with Locust. It mirrors the same user journey as the JMeter version: Browse catalog → Add to cart (N items) → Checkout, against placeholder endpoints served by a tiny local mock backend.
This repo is part of a small series implementing the same scenario in different tools (JMeter, k6, Locust, Gatling) so they can be compared directly.
💡 The script is the easy part. The real value is knowing what to test, shaping the load model, reading the results, and turning them into a go/no-go call — judgment a demo can't capture.
Note. This is a personal portfolio project — a from-scratch reconstruction built entirely on public, open-source tools against a fictional storefront. It is not affiliated with, and contains no material from, any employer or client.
locust/locustfile.py— the test: oneHttpUserwith the 3-step journey, named transactionsmock/— dependency-free mock backend for the 3 placeholder endpointsdocker-compose.yml— one-command demo (mock → Locust headless → HTML report)docs/Proposed_Test_Approach.md— performance testing strategy (SLIs/SLOs, cadence, Agile fit)docs/Project_Brief.md— anonymized project brief / context
docker compose up --buildLocust runs headless (10 users, 60s), waits for the mock to be healthy, and writes
report.html + CSV stats to results/. Open results/report.html when it finishes.
Named transactions (so they group in the report):
- TX_Browse_Catalog —
GET /api/catalog - TX_Add_To_Cart —
POST /api/cart/items×CART_SIZE, correlatescartId - TX_Checkout_PlaceOrder —
POST /api/orderswith unique guest data
catch_response is used to validate status codes (200 / 201) and mark mismatches as failures —
preventing "fast but wrong" results.
- Load: edit
--users/--spawn-rate/--run-timeindocker-compose.yml. - Cart size:
CART_SIZEenv var (default 10). - Interactive UI instead of headless (needs a local Locust):
locust -f locust/locustfile.py --host http://localhost:8080 # then open http://localhost:8089
A run against the local mock backend (all green):
- Endpoints are placeholders; the mock returns the minimal contract (
cartId/orderId) so the journey runs green. - The mock's latencies are illustrative only — this demonstrates the tooling and reporting, not real system performance.
--exit-code-on-error 1makes the container exit non-zero if any request fails (CI-friendly).
The same ShopLite journey (browse → add-to-cart → checkout) is implemented across five load-testing tools (plus a frontend Core Web Vitals one) — each as a one-command Dockerized demo with an HTML report:
| Tool | Language / DSL | SLOs as | Report | Repo |
|---|---|---|---|---|
| Apache JMeter | XML + Groovy | Assertions | HTML dashboard | ShopLite-load-tests |
| Grafana k6 | JavaScript | Thresholds | HTML report | ShopLite-load-tests-k6 |
| Locust | Python | Code-level checks | Built-in HTML | ShopLite-load-tests-locust |
| Gatling | Scala DSL | Assertions | HTML charts | ShopLite-load-tests-gatling-scala |
| Gatling | Java DSL | Assertions | HTML charts | ShopLite-load-tests-gatling-javaDSL |
| sitespeed.io | JavaScript | Budgets | HTML + Grafana | ShopLite-ui-perf |
| Observability | InfluxDB + Grafana | — | Live dashboards | ShopLite-observability |
Sample failure report — red dashboards + a short analysis of one deliberately broken run (errors, KO, slow Core Web Vitals): ShopLite-observability/reports.
