lemoncheesecake-requests

lemoncheesecake-requests provides logging facilities to requests for tests written with the lemoncheesecake test framework.

In this example, we implement a very basic test on a Github API endpoint:

# suites/github.py

import lemoncheesecake.api as lcc
from lemoncheesecake.matching import *
from lemoncheesecake_requests import Session, is_2xx

@lcc.test()
def get_org():
    session = Session(base_url="https://api.github.com")

    resp = session.get("/orgs/lemoncheesecake")
    resp.require_status_code(is_2xx())

    check_that_in(
        resp.json(),
        "id", is_integer(),
        "name", equal_to("lemoncheesecake")
    )

We run the test:

$ lcc.py run
=================================== github ====================================
 OK  1 # github.get_org

Statistics :
 * Duration: 0.214s
 * Tests: 1
 * Successes: 1 (100%)
 * Failures: 0

And here are the report details :

_images/report-sample.png

Installation

Install through pip:

$ pip install lemoncheesecake-requests

lemoncheesecake-requests is compatible with Python 3.6-3.9.

Features

Session

lemoncheesecake-requests extends requests.Session to add logging features through a lemoncheesecake_requests.Logger instance.

This logger which can be set session-wide (it is set to Logger.on() by default):

session = Session(base_url="https://api.github.com", logger=Logger.no_headers())
session.get("/orgs/lemoncheesecake")

or overridden on a per request basis:

session = Session(base_url="https://api.github.com")
session.get("/orgs/lemoncheesecake", logger=Logger.no_headers())

The base_url argument is optional and an extra hint argument is also available to provide more context in the logs to the report reader.

As you might guess from the previous examples, the logger can be fine tuned to control exactly what HTTP request/response details that will be logged through the following logger boolean attributes:

If you want for instance to create a logger that only logs data coming from the response:

logger = Logger(
   request_line_logging=False
   request_headers_logging=False
   request_body_logging=False
)

and then pass this logger to a session or to a specific HTTP method call.

The lemoncheesecake_requests.Logger class also provide class methods to easily create instances for common usage cases:

HTTP request bodies and especially response bodies might be very large and make the final report unreadable. That’s why the logger will log the request/response bodies as attachment if their (serialized) content size exceed a certain size. This size can be configured through the max_inlined_body_size logger attribute.

Response

The various request-methods (get(), post(), etc…) of lemoncheesecake_requests.Session return a lemoncheesecake_requests.Response which extends requests.Response and provides several extra methods to check the response status code.

As you may already know, lemoncheesecake provides three different way (for three different behaviors) to perform a matching operation:

The lemoncheesecake_requests.Response follows the same logic by offering the corresponding three methods:

Where expected can be either an int or a Matcher instance, so that the following statements are all valid:

resp.check_status_code(200)
resp.check_status_code(equal_to(200))
resp.check_status_code(any_of(200, 201))

lemoncheesecake-requests provides the is_2xx(), is_3xx(), is_4xx(), is_5xx() matchers to check status code family:

resp.check_status_code(is_2xx())

There is also an alternative way to check status code, that is not built uppon lemoncheesecake’s logging facilities: Response.raise_unless_status_code(expected) will directly raise a StatusCodeMismatch exception if the condition is not met and then interrupt the test (unless the exception is explicitly caught):

resp.raise_unless_status_code(200)

(this function can also take a Matcher instance as argument).

All these methods have a corresponding shortcut method that directly check a 2xx status code:

It means that those two method calls are equivalent:

resp.check_status_code(is_2xx())
resp.check_ok()

Please note that all these extra methods return the Response instance itself, meaning that they can be chained like this:

resp = session.get("/orgs/lemoncheesecake").require_ok()

See the API Reference for full details about the lemoncheesecake-requests API.

Changelog

The Changelog will tell you about features, improvements and fixes of each version.