Basic

Testing a form without a browser

A form is a route plus a set of fields. The fields can be posted directly, which tests the route and the redirect without any browser at all. That is the cheapest way to prove the interaction works, and it is the shape most login tests take.

What you will see

200 with the jar. Without -b, the same URL is a redirect to login and the test fails for the wrong reason.

About 1 min of reading

Try It

Post both cases of one form

1

Read the action and fields

curl -s http://localhost:3000/login | grep -oE ']*action|]*name="[a-z]+"' | head -5

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

What it prints
The route and the field names the browser would send.
2

Post the accepted case

curl -s -i -c /tmp/jar -d 'email=test@example.com&password=short' http://localhost:3000/login | head -8

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

What it prints
The status line and the Location header. Assert both, not only the status.
3

Post the rejected case

curl -s -i -d 'email=nope&password=x' http://localhost:3000/login | grep -iE '^HTTP|^location' | head -4

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

What it prints
The error route in the Location. If it answers the success route, the validation is broken.
4

Use the jar for a follow-up

curl -s -b /tmp/jar -o /dev/null -w '%{http_code}\n' http://localhost:3000/account

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

What it prints
200 with the jar. Without -b, the same URL is a redirect to login and the test fails for the wrong reason.
Never reuse a real account in a form test. Post a throwaway value to a route that is safe to write to.

Data Flow

Form to an asserted response
1 Read the action and field names
↓
2 Post the accepted case
↓
3 Assert status and Location
↓
4 Post the rejected case and assert the error route
Why this works
The two cases to cover

One accepted submission and one rejected submission. Two cases cover the branch that matters, and they cost one extra request.

Where cookies matter

A route that sets a cookie needs a cookie jar in the test. Without one, a later request looks unauthenticated and the test fails for the wrong reason.

Examples

Post the fields the form sends

Read the action and the input names from the served page, then send the same fields. The test then exercises the same route the browser would.

Assert the redirect target

A successful post usually answers with a redirect. Assert the Location, not only the status, so a wrong target is caught.

Assert the failure too

Post a bad value and assert the error route. A form that always answers success passes a test that never tried a bad input.

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.

← Testing that links go where they should
Previous Lesson
Testing that links go where they should
Next Lesson
Testing state that a page depends on
Testing state that a page depends on →