Basic

Why a frontend needs a different test than a server

A server test calls a function and checks a value. A frontend has no function to call: it has a document, a layout, and an interaction that depends on both. The test has to drive the browser, because the thing under test is the browser's own work.

What you will see

PASS and exit 0. Change the string to something absent and it prints FAIL and exits 1.

About 1 min of reading

Try It

Fetch one served page and assert on it

1

Fetch the served document

curl -s http://localhost:3000/tutorials/lessons | head -20

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The rendered HTML, not the template. The EJS tags are gone.
2

Assert one string is present

curl -s http://localhost:3000/tutorials/lessons | grep -c 'Tutorials'

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A number above zero. Zero means the page does not contain what the test expects.
3

Assert one string is absent

curl -s http://localhost:3000/tutorials/lessons | grep -cE '<%|<%='

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Zero. Any match means an unrendered template reached the user.
4

Put it in a script that fails

printf '#!/bin/sh\ncurl -s http://localhost:3000/tutorials/lessons | grep -q "Tutorials" || { echo FAIL; exit 1; }\necho PASS\n' | tee t1.sh && chmod +x t1.sh && ./t1.sh

Before you run it, say out loud what it will print. Then open the answer.

What it prints
PASS and exit 0. Change the string to something absent and it prints FAIL and exits 1.
Do not point the test at a file on disk. A test that reads the template passes while the served page is broken.

Data Flow

Source to a testable target
1 Template is written in views
↓
2 App renders it with data
↓
3 Server sends the document
↓
4 The test fetches the served document
Why this works
The question each test answers

The HTML test asks: is the document right. The browser test asks: did the interaction work. Pick the cheaper one first, and add the other only when the question needs it.

Why the test runs on the served page

Testing the source template tests the wrong thing. The served page is what the user receives, after the app has rendered it, and it is the only fair target.

Examples

What a unit test cannot see

A unit test can check that a route returns HTML. It cannot check that the page the user sees has a visible heading, or that a button is reachable by keyboard.

Two kinds of frontend test

One kind drives the browser and checks behaviour. The other reads the shipped HTML and checks structure. Both are needed, and they answer different questions.

The cheapest test that still sees the page

Fetching the served HTML and asserting on it costs milliseconds and needs no browser. It catches markup and link bugs, which is most of what breaks on a page.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

Next Lesson
A fetch test: request, status, body
A fetch test: request, status, body →