JS Sketchbooksee JavaScript think ✏️
← back to phase 10

10.2 — The testing pyramid

9.7 planted a flag: “the testing pyramid — lesson 10.2.” Time to pay it. The idea: the same feature can be tested at three layers — and the layers differ in speed by a factor of a THOUSAND. Choosing the layer is therefore not a detail; it decides whether your suite runs in seconds (and gets run) or hours (and gets abandoned).

Three layers, real numbers, one famous shape — and the anti-pattern that eats teams alive.

watch it happen
// the SAME feature, asked at 3 layers
// (a checkout that applies a coupon)

// UNIT — one machine, isolated (~5ms)
expect(applyCoupon(1000, "SAVE10"))
  .toBe(900);

// API — pieces wired, no browser (~300ms)
const res = await request.post("/api/checkout",
  { data: { total: 1000, coupon: "SAVE10" } });
expect(res.status()).toBe(200);

// E2E — whole system, real browser (~8s)
await page.fill("#coupon", "SAVE10");
await page.click("text=Apply");
await expect(page.locator(".total"))
  .toHaveText("₹900");

The code pane shows ONE feature — a checkout coupon — asked about at three layers. Same behavior under test, three completely different price tags. Read all three blocks once before we zoom in.

the testing pyramidUNIT — functions in isolation~5ms eachAPI / INTEGRATION — pieces wired~300ms eachE2E — real browser~8s eachone feature, three possible questions — at three very different prices
under the hood

The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”

The boundary between “unit” and “integration” is genuinely fuzzy and teams argue about it for sport — is a function plus its real helper two units or one integration? Don’t get stuck: the load-bearing distinction is touches the outside world or not (network, disk, browser, clock). Inside-only = fast lane; outside-touching = slow lane. 10.6’s test doubles exist precisely to move tests INTO the fast lane.

Real numbers behind the estimates: a browser E2E test pays for launching a browser context, loading a page, network round-trips (6.7), rendering (7.8), and auto-waiting pauses (11.6 will formalize them). None of that is waste — it’s exactly WHY it proves so much — but it can’t be made free, only paralleled (11.15).

The pyramid has respectable critics — you’ll meet the “testing trophy” (which fattens the integration band, arguing modern tools made it cheap). The disagreement is about the middle band’s size; NOBODY credible argues for the cone. Both camps agree on this lesson’s core: many fast tests below, few browser tests above.

Job note: “where would you test this?” is a beloved interview question. The winning shape of an answer is the one from the last step — name the layer, justify by cost and by what failure at that layer would tell you. You just practiced it three times.

your turn

⌨️ the suite health check

You inherit a test plan. Compute its shape and its runtime — and let the numbers, not opinions, say whether it’s a pyramid or a cone.

requirements:

  • Create plan: an array of 9 test objects — { name: "…", layer: "unit" } × 6, layer: "api" × 2, and layer: "e2e" × 1 (names are yours to invent).
  • Count each layer with a reusable countLayer(plan, layer) (4.9’s filter + length) and print the shape line: 6 unit · 2 api · 1 e2e (a template literal builds it).
  • Compute the total runtime in milliseconds — unit tests cost 5, api 300, e2e 8000 — and print it as 8630ms.
  • Print the verdict: healthy pyramid when unit tests outnumber e2e tests, ice-cream cone otherwise.

when you press RUN, the console must show exactly:

6 unit · 2 api · 1 e2e
8630ms
healthy pyramid

✏️ Quick check 1

“Is the coupon math correct for 1000 minus 10%?” — which layer should ask this: unit, api, or e2e?

✏️ Quick check 2

A suite with 40 E2E tests and 3 unit tests has a famous nickname. What is it?

✏️ Quick check 3

500 unit tests at ~5ms each — roughly how many SECONDS is the whole run? (nearest whole number)

teach it back

🗣️ Now teach it back

Draw the pyramid for a friend: define the three layers precisely, give the speed math that justifies the shape, explain what the ice-cream cone is and why teams fall into it, and say where Playwright sits.

Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.

a few sentences, minimum — you’ve got this
to remember
Three layers by how much system a test touches: UNIT (one isolated function, ~5ms, failure pinpoints) · API/INTEGRATION (pieces wired, ~300ms, no browser — 9.7 lives here) · E2E (whole system in a real browser, ~seconds, proves the user’s path).
The shape is a budget: 500 unit ≈ 3s vs 500 E2E ≈ an hour — and an unrun suite catches nothing. Many cheap below, few precious above. The inverse (ice-cream cone) dies of slowness and flakiness.
Playwright owns the top and serves the middle (request). Governing skill: ask each question at the CHEAPEST layer that can answer it — coupon math is a unit question; “can a user buy?” is worth browser-seconds.
next: 10.3 Anatomy of a test →