JS Sketchbooksee JavaScript think ✏️
← back to phase 10

10.1 — Why software breaks

Here’s the uncomfortable truth this entire phase is built on: most bugs aren’t written — they’re CAUSED, by a correct-looking change to code that something else silently depended on. You’re about to watch one happen, mechanically, with tools you already own: a shared helper, a dependency graph, and one string where a number was expected.

Then the two questions that define the job you’re training for: what does catching that bug COST at each stage — and what exactly does a test suite buy?

watch it happen
// monday — a tiny helper, used EVERYWHERE
function formatPrice(amount) {
  return "₹" + amount;
}
// cart.js imports it · invoice.js imports it
// email.js imports it · search.js imports it

// friday — invoices need two decimals:
function formatPrice(amount) {
  return "₹" + amount.toFixed(2);
}
// invoice page checked by hand ✓ … shipped

// but cart.js feeds it a FORM value —
// and form values are STRINGS (1.11):
formatPrice(quantityInput.value);
// "3".toFixed is not a function 💥

Monday. formatPrice is a tiny helper — three lines — and four files import it (8.1’s graph, drawn for one function). This shape is EVERYWHERE in real code: write once, depend often. Remember the arrows; they’re about to matter.

formatPricethe shared helpercart.jsinvoice.jsemail.jssearch.jsone helper, four dependents — 8.1’s dependency graph, drawn for a singlefunction
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 word for what bit cart.js is a contract: formatPrice’s old, unwritten contract was “accepts anything + can glue” (1.9 — strings included); the new code silently narrowed it to “numbers only.” Most regressions are exactly this: an unwritten contract, narrowed without anyone noticing. Tests make contracts written — and 8.5’s TypeScript makes some of them checkable before running (amount: number would have flagged the string caller at the desk stage).

The cost curve isn’t folklore — it’s one of the oldest measured results in software engineering, and while the exact multipliers vary by study, the shape never does: each stage a bug survives multiplies its price, with production an order of magnitude worse than anything before it. That shape is why companies pay people specifically to catch bugs early — your future job is literally an arbitrage on this curve.

Precision on “regression”: teams also use it as an adjective — regression testing (re-running existing checks to catch regressions) and a regression suite (the collection of those checks). Same idea, three grammatical costumes; you’ll hear all three in your first week.

Job note: when interviewers ask “why do we test?”, weak answers say “to find bugs.” You now have the strong one: to make change safe — catching regressions in seconds instead of production, at desk prices instead of 2am prices — plus a specification that can’t rot. That answer signals a professional.

your turn

⌨️ build a regression detector

Two health reports of the same app: before and after friday’s change. Write the program that spots exactly what regressed — the seed of every test suite you’ll ever run.

requirements:

  • Create before as { cart: "ok", invoice: "ok", email: "ok", search: "ok" } and after as the same object but with cart set to "broken".
  • Write findRegressions(before, after): return the names of every feature that was "ok" before and is NOT "ok" now — walk the keys (4.8) and keep the guilty ones (4.9).
  • Print each regressed name, then a summary line: 1 regression found — the count computed, never typed.

when you press RUN, the console must show exactly:

cart
1 regression found

✏️ Quick check 1

A feature that worked last week breaks because of THIS week’s change to a different file. What is that called? (one word)

✏️ Quick check 2

Where is the SAME bug cheapest to fix — at your desk, in QA, or in production?

✏️ Quick check 3

A test suite is fully green. Does that PROVE the app has no bugs? Type yes or no.

teach it back

🗣️ Now teach it back

Tell the formatPrice story to a friend: what changed, why a different file broke, what that’s called — then the cost curve, and the two things a test suite actually buys (plus its one honest limit).

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
A REGRESSION = something that worked, broken by a later change — and it surfaces far from the change (shared code = invisible coupling; the graph’s arrows carry consequences).
The cost curve: desk (minutes) → review (hours) → QA (days) → production (money, trust, 2am) — the same bug multiplies in price at every stage it survives.
Tests buy (1) automated re-asking of every “does X still work?” after every change, and (2) executable specification that can’t rot. Honest limit: green shows presence-of-bugs-checked, never absence — choosing the questions is the craft.
next: 10.2 The testing pyramid →