Start learning free

LESSON 141 OF 188 · BACKEND: TESTS AND RUNNING IT

Logging

Practice

On a server nobody watches the screen, so print is no help there. Instead the shop writes a log: lines that are kept, so you can read them later, for example when a customer says their order went wrong. Python's logging module writes those lines, and each one gets a level: INFO for things that went as planned, WARNING for something unusual. The line logging.basicConfig(level=logging.INFO) at the top makes the log show INFO lines and above.

You give logging.info a text with %s in it, then the values: each value goes in place of the next %s, in order. In a sign-up route, for example:

logging.info("New user: %s, age %s", name, age)

With name "Ana" and age 30, the log gets the line INFO:root:New user: Ana, age 30: the level, the name of the log (root, the main one) and the message.

Test the log too, because a log line can break without anyone noticing. While the lines inside a with self.assertLogs(level="INFO") as logs: block run, every line logged at INFO or above is collected, and if none is, the test fails. After the block, logs.output is the list of the collected lines, each written like the one above.

The check places three orders and shows what your shop logged for each:

POST /orders {"product_id": 1, "quantity": 2}  →  201
  log: INFO:root:Order placed: 2 x Mug, total 24
POST /orders {"product_id": 6, "quantity": 3}  →  201
  log: INFO:root:Order placed: 3 x Teapot, total 66
POST /orders {"product_id": 99, "quantity": 1}  →  404
  log: WARNING:root:Order for unknown product 99

Your task: log every placed order with logging.info and every order for an unknown product with logging.warning. Then write test_order_is_logged, which posts 2 Mugs inside an assertLogs block and checks that logs.output holds exactly the expected line. The check runs it on the shop, where it must pass, and on two broken copies, one that logs nothing and one that logs the price instead of the total, where it must fail.


Assignment
Follow the Coding Tutorial to log the orders with logging.info and logging.warning, and to write a test that reads the log with assertLogs.


Hint
Put each log line right before its return, where everything it needs is known. In logs.output, each line is the level, the log's name and the message, joined by colons: "INFO:root:…".


STEP 1 OF 6
    Ctrl + Enter to check