Skip to main content

Test utility for validating OpenAPI response documentation

Project description

PyPI Coverage Python versions Django versions

Maintainability Rating Reliability Rating Quality Gate Status

DRF OpenAPI Tester

This is a test utility to validate DRF Test Responses against OpenAPI 2 and 3 schema. It has built-in support for:

  • OpenAPI 2/3 yaml or json schema files.
  • OpenAPI 2 schemas created with drf-yasg.
  • OpenAPI 3 schemas created with drf-spectacular.

Installation

pip install drf-openapi-tester

Usage

First instantiate one or more instances of SchemaTester:

from openapi_tester import SchemaTester

schema_tester = SchemaTester()

If you are using either drf-yasg or drf-spectacular this will be auto-detected, and the schema will be loaded by the SchemaTester automatically. If you are using schema files though, you will need to pass the file path to the tester:

from openapi_tester import SchemaTester

# path should be a string
schema_tester = SchemaTester(schema_file_path="./schemas/publishedSpecs.yaml")

Once you instantiate a tester, you can use it to test responses:

from openapi_tester.schema_tester import SchemaTester

# you need to create at least one instance of SchemaTester.
# you can pass kwargs to it
schema_tester = SchemaTester()


def test_response_documentation(client):
    response = client.get('api/v1/test/1')
    assert response.status_code == 200
    schema_tester.validate_response(response=response)

If you are using the Django testing framework, you can create a base APITestCase that incorporates schema validation:

from openapi_tester.schema_tester import SchemaTester
from rest_framework.test import APITestCase
from rest_framework.response import Response

schema_tester = SchemaTester()


class BaseAPITestCase(APITestCase):
    """ Base test class for api views including schema validation """

    @staticmethod
    def assertResponse(response: Response, **kwargs) -> None:
        """ helper to run validate_response and pass kwargs to it """
        schema_tester.validate_response(response=response, **kwargs)

Then use it in a test file:

from shared.testing import BaseAPITestCase


class MyAPITests(BaseAPITestCase):
    def test_some_view(self):
        response = self.client.get("...")
        self.assertResponse(response)

Options

You can pass options either globally, when instantiating a SchemaTester, or locally, when invoking validate_response:

from openapi_tester import SchemaTester, is_camel_case
from tests.utils import my_uuid_4_validator

schema_test_with_case_validation = SchemaTester(
    case_tester=is_camel_case,
    ignore_case=["IP"],
    validators=[my_uuid_4_validator]
)

Or

from openapi_tester import SchemaTester, is_camel_case
from tests.utils import my_uuid_4_validator

schema_tester = SchemaTester()


def my_test(client):
    response = client.get('api/v1/test/1')
    assert response.status_code == 200
    schema_tester.validate_response(
        response=response,
        case_tester=is_camel_case,
        ignore_case=["IP"],
        validators=[my_uuid_4_validator]
    )

case_tester

The case tester argument takes a callable that is used to validate the key casings of both schemas and responses. If nothing is passed, case validation is skipped.

The library currently has 4 built-in case testers:

  • is_pascal_case
  • is_snake_case
  • is_camel_case
  • is_kebab_case

You can of course pass your own custom case tester.

ignore_case

List of keys to ignore when testing key casing. This setting only applies when case_tester is not None.

validators

List of custom validators. A validator is a function that receives two parameters: schema_section and data, and returns either an error message or None, e.g.:

from typing import Any, Optional
from uuid import UUID


def my_uuid_4_validator(schema_section: dict, data: Any) -> Optional[str]:
    schema_format = schema_section.get("format")
    if schema_format == "uuid4":
        try:
            result = UUID(data, version=4)
            if not str(result) == str(data):
                return f"Expected uuid4, but received {data}"
        except ValueError:
            return f"Expected uuid4, but received {data}"
    return None

field_key_map

You can pass an optional dictionary that maps custom url parameter names into values, for cases where this cannot be inferred by the DRF EndpointEnumerator. A concrete use case for this option is when the django i18n locale prefixes.

from openapi_tester import SchemaTester

schema_tester = SchemaTester(field_key_map={
  "language": "en",
})

Schema Validation

When the SchemaTester loads a schema, it runs it through OpenAPI Spec validator which validates that the schema passes without specification compliance issues. In case of issues with the schema itself, the validator will raise the appropriate error.

Known Issues

  • We are using prance as a schema resolver, and it has some issues with the resolution of (very) complex OpenAPI 2.0 schemas. If you encounter issues, please document them here.

Contributing

Contributions are welcome. Please see the contributing guide

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drf-openapi-tester-2.0.1.tar.gz (18.4 kB view details)

Uploaded Source

Built Distribution

drf_openapi_tester-2.0.1-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file drf-openapi-tester-2.0.1.tar.gz.

File metadata

  • Download URL: drf-openapi-tester-2.0.1.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.9.12 Linux/5.13.0-1021-azure

File hashes

Hashes for drf-openapi-tester-2.0.1.tar.gz
Algorithm Hash digest
SHA256 de7223c3b836cfcccc9d2c7ee8580bc9b38aa105f0a486d335cb5b917ac4be86
MD5 c67615876139dd50e24a4fbeae78a010
BLAKE2b-256 e5693065b5839f5900325c3c841416351d4b9f5da1d18d2535755ede9d5c10a0

See more details on using hashes here.

File details

Details for the file drf_openapi_tester-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: drf_openapi_tester-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.9.12 Linux/5.13.0-1021-azure

File hashes

Hashes for drf_openapi_tester-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8216c62ea0cc04eabd9e1b4969687fd20c66a575beb2eb436483d37231d7484b
MD5 793e78bfbb8a09153d63866336536084
BLAKE2b-256 56f072d3ceb2b17296c89c119f72b3c6c5843ffd48e2aa2b33ad7d9b58bdf112

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page