Start learning free

LESSON 146 OF 173 · BACKEND: TESTS AND RUNNING IT

Project: Test the Checkout in Go

Practice

A test suite is a set of tests that run together, one for each thing that must keep working. The shop's checkout takes real money, so it deserves one. It is built for you, hidden, by newApp(): POST /checkout takes a cart like {"items": [{"product_id": 1, "quantity": 2}]}, adds up the prices from the database, charges the card through the payment provider and answers 201 with {"status": "paid", "total": 24}.

A good suite tests the normal case and the edge cases, where bugs like to hide. Each test sends one request and checks the status code and the whole body. Here is one test of that shape, for a shop's product page:

func (s *ShopTests) TestMissingProduct() {
    response, _ := http.Get(s.server.URL + "/products/99")
    s.Equal(404, response.StatusCode)
    s.Equal(map[string]any{"error": "Product not found"}, readJSON(response))
}

Your suite sends three carts. A Mug (product 1) costs 12, a Pen (product 4) costs 2 and a Gift card (product 8) costs 50. The payment provider's test mode declines every payment over 1000. Work the expected answers out by hand, never with the code you are testing: a test that repeats the code's calculation repeats its bugs too.

POST /checkout  2 Mugs + 5 Pens   →  201  {"status": "paid", "total": 34}
POST /checkout  {"items": []}     →  400  {"error": "The cart is empty"}
POST /checkout  25 Gift cards     →  402  {"error": "Payment declined"}

When you run the code, the check runs your suite on the checkout, where all three tests must pass (3 tests: OK). Then it runs it on three broken copies of the checkout, and each copy must fail at least one test.

Your task: CheckoutTests is started for you: its SetupTest runs newApp() on a test server in s.server, and TestCheckoutSucceeds already has its cart. Finish that test, then write TestEmptyCart and TestDeclinedCard. Each one posts its cart to /checkout and checks the status code and the JSON body with s.Equal.


Assignment
Follow the Coding Tutorial to write a test suite for the checkout: a paid order, an empty cart and a declined card.


Hint
Every test has the same shape: post the cart with http.Post(s.server.URL+"/checkout", "application/json", strings.NewReader(cart)), then one s.Equal for response.StatusCode and one for readJSON(response). Go won't compile while response is unused, so the code runs again once its first check is in. Work out each expected total on paper first.


STEP 1 OF 12
    Ctrl + Enter to check

    Test Project in Go

    Keep going with Go1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free