Services Blog Français

cli2 chttpx automated test fixture writing

| by jpic | cli cli2 chttpx devops dev

chttpx also registers as a pytest plugin, because as you know, I’m pretty lazy when it comes to repetitive test writting which is why I developed django-dbdiff and django-responsediff and also cli2.test.autotest. Let’s have the same thing with chttpx!

Let’s write a test that calls the object create and delete command, say, in the tests/test_client_test.py file:

@pytest.fixture
def test_name(ts, chttpx_vars):
    # ts is a fixture provided by this plugin which contains the timestamp
    # chttpx_vars is variables that will be attached to the test fixture
    # doing this ensures you get either the fixture saved test_name either
    # a new one, unique thanks to the timestamp
    return chttpx_vars.setdefault('test_name', f'test{ts}')


@pytest.mark.chttpx_mock
def test_object_story(test_name):
    obj = APIClient.cli['object']['create'](f'name={test_name}')
    assert obj.name == test_name

    with pytest.raises(chttpx.RefusedResponseError):
        # test_name already exists!
        APIClient.cli['object']['create'](f'name={test_name}')

    APIClient.cli['object']['delete'](f'{obj.id}')

The first time you run this test, our example APIClient will connect to localhost:8000 as it’s configured by default, and actual queries will be exeuted:

[21/Mar/2025 10:35:11] "POST /objects/ HTTP/1.1" 201 38
Bad Request: /objects/
[21/Mar/2025 10:35:11] "POST /objects/ HTTP/1.1" 400 50
[21/Mar/2025 10:35:11] "GET /objects/121/ HTTP/1.1" 200 38
[21/Mar/2025 10:35:11] "DELETE /objects/121/ HTTP/1.1" 204 0

And the chttpx_mock pytest marker will cause new contents to be written for you in tests/fixtures/tests_test_client_test.py::test_object_story.yaml:

    - request:
        event: request
        json:
          name: test33312
        level: debug
        method: POST
        timestamp: '2025-03-21 10:38:29'
        url: http://localhost:8000/objects/
      response:
        event: response
        json:
          data: {}
          id: 122
          name: test33312
        level: info
        method: POST
        status_code: '201'
        timestamp: '2025-03-21 10:38:29'
        url: http://localhost:8000/objects/
    - request:
        event: request
        json:
          name: test33312
        level: debug
        method: POST
        timestamp: '2025-03-21 10:38:29'
        url: http://localhost:8000/objects/
      response:
        event: response
        json:
          name:
          - object with this name already exists.
        level: info
        method: POST
        status_code: '400'
        timestamp: '2025-03-21 10:38:29'
        url: http://localhost:8000/objects/
    # and so on ...

You are supposed to add this file in git, because next time you run the test: the chttpx_mock marker will provision pytest-httpx’s httpx_mock will all the request/responses that have been recorded in the fixture file.

As such, two new pytest options are added by the chttpx plugin:

  • --chttpx-live: don’t use fixtures at all, run against the real network
  • --chttpx-rewrite: force rewriting all fixtures

When specifications change, you can remove a given test fixture and run the test again which will rewrite it, or, run with --chttpx-rewrite to rewrite all fixtures.

Because your fixtures are in git, this will cause a diff in the fixtures file that you will need to review. It’s your responsibility to review these changes properly, we just write the test fixtures for you, but you have to proof-read them!

Released in chttpx 5.1.2!

Have fun and profit ;)

They trust us

Contact

logo