Guide

User journey testing: test what people actually do

A user journey test follows one task through your product, from signing in to the result, the way a real user in a real role does it. It answers the question unit tests can’t: can this person still get this done?

What user journey testing is

A user journey is a task someone completes in your product: an employee orders a product, a new customer finishes onboarding, a company admin invites a colleague. User journey testing runs that task end to end, as that user, and checks every step on the way.

It sits between two kinds of tests most teams already have. Unit and integration tests check pieces in isolation, so they pass while the pieces no longer fit together. Manual click-throughs check the whole, but only when someone has time. A journey test is the whole, repeatable, and it runs without a person watching.

Journey tests are usually written against the API, because that is where the rules live: who may see what, which fields a create needs, what a role is refused. A journey test that only clicks through the screens checks the UI; one that walks the API checks the product.

Why it matters

  • Breakage between components. Each service passes its own tests, but the order no longer reaches the invoice because a field was renamed on one side.
  • Role and tenant rules. A journey per role shows what each role can do, and a refusal step shows what it can’t. Access bugs rarely show up in tests written as one all-powerful user.
  • Deploys. Running the journeys after every deploy turns “the release looks fine” into a check: did onboarding, ordering and sign-in still work?
  • A shared picture. A journey with one lane per role is something product, QA and engineering can read together, which a folder of test files is not.

How to set up journey tests, with any tool

  1. List the journeys that would hurt most if they broke: sign-in, onboarding, the core purchase or workflow, and the admin tasks behind them. Start with three to five.

  2. Write each one down as a short sentence per role: who signs in, what they see, what they create or change, and what they must not be able to do.

  3. Give every role its own test account, signed in the way real users sign in (OAuth, a login form, single sign-on), not with a shared service token.

  4. Chain the steps: each one uses what earlier steps returned (the id of the order just created), and makes its own data with unique names, so runs don’t trip over each other.

  5. Add checks that say what success means: status codes, fields in the answer, how long it may take, and the refusals you expect.

  6. Run them against a test environment by hand, then after every deploy, then on a schedule with an alert when one starts failing.

Common pitfalls

  • Testing as an admin only. Everything passes for the role that may do everything. Write the journey for the roles your customers actually use.
  • Shared, hand-made test data. Journeys that depend on one record someone created by hand fail when someone else changes it. Let each run create what it needs, and clean up after itself.
  • Checking only status 200. A list that answers 200 with another tenant’s records is a failure. Check the fields that matter.
  • Tests nobody can read. If only the person who wrote the test understands it, it stops being updated. Keep the journey readable as a sentence.
  • Running them rarely. A journey test that runs once a sprint finds the problem after your users do. Run them on every deploy and on an interval.

How Journey Lanes does it

Journey Lanes reads your repositories or API descriptions first, so a journey starts from your real endpoints, records and roles (sources and scanning). You describe the journey in plain language; it draws a flow with one lane per role, picks the endpoints, and adds the checks the sentence promises (flows from plain language).

For example, this sentence:

Describe the journey

An employee logs in. The employee sees the products and orders a product. The employee sees their orders.

The flow Journey Lanes draws from the sentence above Employee: Log in via Keycloak, then Products (GET /api/products), then Order product (POST /api/orders), then Orders (GET /api/orders). EmployeeROLE_EMPLOYEE Mock backendCollections Screen Products GET /api/products Action Order product POST /api/orders Screen Orders GET /api/orders Data Product Mock collection Data Order Mock collection
  1. EmployeePOST /realms/portal/protocol/openid-connect/token200
  2. EmployeeGET /api/products200
  3. EmployeePOST /api/orders201
  4. EmployeeGET /api/orders200
Drawn by Journey Lanes’ rules engine from the sentence above, against a sample portal API, then run against the mock backend.

Every step can be edited by hand, the flow runs against a mock backend built from your code or your live environments with each role signed in its own way, and the same flow can be monitored on an interval or run after every deploy.

Questions

What is the difference between a user journey test and an end-to-end test?

The terms overlap. An end-to-end test is any test that runs through the whole system; a user journey test is an end-to-end test organised around one task of one user, with a role, a goal and the steps to reach it.

Do journey tests replace unit tests?

No. Unit tests find a broken function quickly and precisely; journey tests find the problems between components and roles. Most teams need a few journey tests per important task and many unit tests.

Should journey tests go through the UI or the API?

Both have a place. Tests through the API are faster and more stable and check the rules the backend enforces; tests through the browser check what people see. Journey Lanes tests journeys through the API.

Draw your first journey test

Connect a repository or an OpenAPI document and describe one journey; it runs against the mock straight away.