Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

test-har

Use HTTP Archive (HAR) files in Python tests

To send this request to an API backend and assert the API response matches this response…

{
  "log": {
    "version": "1.2",
    "entries": [
      {
        "request": {
          "method": "POST",
          "url": "mock://example.com/users/",
          "headers" : [
            {
              "name": "Accept",
              "value": "application/json"
            }
          ],
          "postData": {
            "mimeType": "application/json",
            "text" : {
              "username": "foo_username",
              "email": "foo@example.com",
              "group": "479e75e6-755a-46f1-a949-d6fee3671b3c"
            }
          },
          "comment" : "Test validation errors"
        },
        "response": {
          "status": 201,
          "statusText": "Created",
          "headers" : [
            {
              "name": "Allow",
              "value": "GET, POST, HEAD, OPTIONS"
            },
            {
              "name": "Vary",
              "value": "Accept, Cookie"
            }
          ],
          "content": {
            "mimeType": "application/json",
            "text": {
              "username": "foo_username"
            }
          }
        }
      }
    ]
  }
}

Use this test:

import datetime

# Import the appropriate backend for your framework.
# Currently there are backends for the `requests` library...
from test_har.requests_har as test_har
# and for the Django ReST Framework.
# from test_har.django_rest_har as test_har
# Contributions for other frameworks welcome!

from .. import models


class MyAPITest(test_har.HARTestCase):
    """
    Specify the HAR file to use by default.
    """

    # Path to file relative to this test file
    # Set to `None` to skip automatic HAR parsing and set up
    example_har = 'example.har.json'

    def test_my_response(self):
        """
        Write your test as you would.
        """
        # For convenience, `self.example` is the parsed JSON in
        # `self.example_har`, `self.entry` is the first request/response
        # entry from `log/entries/0` in the HAR., `self.headers` is a
        # dictionary of the response headers for that entry, and
        # `self.content` is the response body content from that entry.

        # Make any changes to the test fixture necessary for the test such
        # as creating related objects before a POST that requires them.
        group = models.Group(
            name='foo_group',
            uuid=self.entry["request"]["postData"]["text"]["group"])

        # Make any changes to the HAR necessary for the assertions to work
        # before sending the requests
        self.content["some_dynamic_value"] = models.my_dynamic_function()

        # Send the HAR requests, assert responses match the HAR, and return
        # the responses.  Currently, assertions are made against the
        # response: `Status` code, `Status` reason text, `Content-Type`
        # MIME type, other headers in the HAR, and the response body
        # content.  If the response MIME type is a JSON type,
        # then assertions will be made against each top-level key
        # individually and ignore any key in the response not included in
        # the HAR.
        now = datetime.datetime.now()
        responses = self.assertHAR(self.example)

        # Make any other assertions, or do anything else you'd like to do,
        # with the responses.
        self.assertAlmostEqual(
            datetime.strptime(response[0].json()['created'], format='...'),
            now, delta=datetime.timedelta(seconds=1),
            msg='Wrong automatic creation time')

    def test_my_other_response(self):
        """
        Test a different HAR file.
        """
        # Replace `self.example` and the other convenience attributes with
        # the content form another HAR file
        self.setUpHAR('other.har.json')
        responses = self.assertHAR(self.example)
        ...

Why?

Writing tests for API backends can often involve a lot of repetitive code in the tests to construct the content either to POST to the API or the expected content in the response against which to make assertions. For example, constructing a Python dictionary to represent the JSON POSTed to or returned from the API. Similarly, testing the returned content often requires many detailed assertions in order to sufficiently cover how the API should behave.

While writing this repetitive test code is tedious, more importantly, it isn’t very readable and makes discerning the intended behavior the test is meant to cover unnecessarily difficult. Ideally, one should be able to describe the expected behavior of the API in a format much closer to the format used by the API. Also ideally, one should be able to clearly read related requests and responses together.

The JSON-based HTTP Archive (HAR) format used by browsers for recording browser sessions gives us exactly such a format, especially for JSON-based APIs. The test_har package provides support for using HAR files to drive tests and make the more common assertions against the response while still allowing the developer to continue doing anything not able to be covered using the HAR file the same way they would have otherwise.

Metadata

Release files for test-har 0.2.dev0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for test-har 0.2.dev0
File Size Uploaded Provenance Actions
test-har-0.2.dev0.tar.gz 12.6 kB Without provenance Details for test-har-0.2.dev0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for test-har 0.2.dev0
File Interpreter ABI Platform Actions
test_har-0.2.dev0-py3-none-any.whl Python 3 none any Details for test_har-0.2.dev0-py3-none-any.whl

Total release size: 29.5 kB

Release files / test-har-0.2.dev0.tar.gz

Download URL test-har-0.2.dev0.tar.gz
Size 12.6 kB
Tags Source
SHA-256 checksum
How to use checksums
a771f8aac1c9e9989f68d76c53a952b0cf8960531de853c9b25fca73c82aa7eb
BLAKE2b-256 checksum
How to use checksums
20615b56c49f4f64a759c15a79e28a4547a2a468edb17988d1c53719dec0f4bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / test_har-0.2.dev0-py3-none-any.whl

Download URL test_har-0.2.dev0-py3-none-any.whl
Size 17.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8cfe5437d7cd73d91fda8f46a8e5a4755b96b531753382ddc7a73fdd603df97d
BLAKE2b-256 checksum
How to use checksums
13475bb98fa57c8f0221d30e133cd26ec13e28aa9e5b32512839f745ff334627
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Security for test-har 0.2.dev0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page