Day 16 of 20

The truthful red

A boundary test fails at exactly 10,000 JMD. Do not fix the test.

Lesson 17 of 210 complete

Every red you read yesterday was one you caused; today the store causes one, and this is the lesson the whole course has been walking toward. The store’s discount note makes a written promise: IRIE20 gives 20% off orders of 10,000 JMD or more. “Or more” makes 10,000 exactly a boundary, and Day 13 told you where money bugs live. Two dishes land the cart on the edge: the Full Jerk Combo at 8,200 plus the Baked Cheese Patty at 1,800 is exactly 10,000.

Teach the page object the discount form:

this.discountLine = page.getByTestId('cart-discount');
this.discountMessage = page.getByTestId('discount-message');

async applyDiscount(code) {
  await this.page.getByTestId('discount-code').fill(code);
  await this.page.getByTestId('discount-apply').click();
}

Then the boundary test. Twenty percent of 10,000 is 2,000, so:

test('verify that IRIE20 gives 2,000 JMD off an order of exactly 10,000 JMD', async () => {
  await store.addToOrder('Full Jerk Combo');
  await store.addToOrder('Baked Cheese Patty');

  await store.applyDiscount('IRIE20');

  await expect(store.discountLine).toHaveText('-2,000 JMD');
});

Run it:

✘ verify that IRIE20 gives 2,000 JMD off an order of exactly 10,000 JMD (6.3s)

  Error: expect(locator).toHaveText(expected)

  Expected string: "-2,000 JMD"
  Received string: "0 JMD"

Ask the three questions in order. Did the test reach the behaviour: yes, every step executed. Is the assertion wrong or too strict: read the store’s own promise again; 10,000 is “10,000 or more”. So it is question three. The code behind that note checks for more than 10,000 when the promise says or more, and exactly 10,000 gets nothing. If you took QA Fundamentals, you caught this by hand there; your machine just caught it without being asked.

Look one line above the discount too: the message cheerfully reports the code was applied while the money line says 0 JMD. If you had asserted on the message, you would be green right now, and wrong. Test the promise, not the toast.

The response that ruins suites

Here is the wrong fix, and I have watched real teams reach for it:

// The wrong fix. This makes the suite agree with a broken product.
await expect(store.discountLine).toHaveText('0 JMD');

That test now passes, documents the bug as intended behaviour, and will fail on the day someone fixes the product. Making the suite agree with a broken product is how suites become liars. Never edit a test to match behaviour you know is wrong.

The right response: the test stays exactly as written, the bug gets filed, and the failure output above goes into the ticket as evidence, expected against received in the product’s own words. This red stays red for the rest of the course, through the capstone, on purpose. It is not a broken test. It is your suite doing the exact job it exists for: catching a real bug before a customer pays for it.

Do this today

Write the boundary test, watch it fail, and file the bug with the output as evidence. Then pin the break to the boundary with two companion tests: the Full Jerk Combo alone at 8,200 expects a discount line of 0 JMD and passes, and those two dishes plus the Deluxe Plantain Plate, 14,500 in total, expects -2,900 JMD and passes. Below green, at red, above green: the trio proves the feature works and the boundary is broken, which is exactly the sentence for the ticket. Tomorrow: the reds that are less honourable, flake and maintenance.

Before you move on

Do the practice, then mark it complete

Completion is for you. It means you produced the evidence the lesson asked for, not only that you reached the bottom of the page.