跳转到主要内容

OpenAPI响应文档验证测试工具

项目描述

PyPI Coverage Python versions Django versions

DRF OpenAPI Tester

这是一个测试工具,用于验证DRF测试响应是否与OpenAPI 2和3模式匹配。它内置了对以下内容的支持:

  • OpenAPI 2/3 yaml或json模式文件。
  • 使用drf-yasg创建的OpenAPI 2模式。
  • 使用drf-spectacular创建的OpenAPI 3模式。

安装

pip install drf-openapi-tester

使用方法

实例化一个或多个SchemaTester实例

from openapi_tester import SchemaTester

schema_tester = SchemaTester()

如果您正在使用 drf-yasgdrf-spectacular,这将自动检测,并且模式将由 SchemaTester 自动加载。

如果您使用模式文件,则需要传递文件路径。

from openapi_tester import SchemaTester

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

一旦实例化了一个测试器,您就可以用它来测试响应。

from openapi_tester.schema_tester import SchemaTester

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)

如果您使用 Django 测试框架,可以创建一个包含模式验证的基 APITestCase

from rest_framework.response import Response
from rest_framework.test import APITestCase

from openapi_tester.schema_tester import SchemaTester

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)

然后在测试文件中使用它。

from shared.testing import BaseAPITestCase


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

选项

您可以在实例化 SchemaTester 时全局传递选项,或者在调用 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]
)

或者

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

case_tester 参数接受一个可调用的对象,用于验证模式和响应的关键案例。如果不传递任何内容,则跳过案例验证。

该库目前有 4 个内置的案例测试器

  • is_pascal_case
  • is_snake_case
  • is_camel_case
  • is_kebab_case

您可以使用这些之一,或您自己的。

ignore_case

在测试关键案例时忽略键的键值列表。此设置仅在 case_tester 不为 None 时适用。

validators

自定义验证器列表。验证器是一个函数,它接收两个参数:模式部分和数据,并返回错误消息或 None,例如。

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

您可以通过传递一个可选的字典将自定义 URL 参数名称映射到值,在这种情况下,这不能由 DRF EndpointEnumerator 推断。此选项的一个具体用例是当使用 django i18n locale prefixes 时。

from openapi_tester import SchemaTester

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

模式验证

当 SchemaTester 加载模式时,它使用 OpenAPI 规范验证器 进行解析。这验证了模式。如果模式本身存在问题,验证器将引发适当的错误。

Django 测试客户端

该库包括一个 OpenAPIClient,它扩展了 Django REST 框架的 APIClient。如果您希望在编写单元测试时针对 OpenAPI 模式验证每个响应,则 OpenAPIClient 就是您需要的!

要使用 OpenAPIClient,只需传递一个用于验证响应的 SchemaTester 实例,然后像常规 Django 测试客户端一样使用它。

schema_tester = SchemaTester()
client = OpenAPIClient(schema_tester=schema_tester)
response = client.get('/api/v1/tests/123/')

要强制所有在项目中工作的开发者使用 OpenAPIClient,只需覆盖 client 修复(当使用 pytestpytest-django 时)。

from pytest_django.lazy_django import skip_if_no_django

from openapi_tester.schema_tester import SchemaTester


@pytest.fixture
def schema_tester():
    return SchemaTester()


@pytest.fixture
def client(schema_tester):
    skip_if_no_django()

    from openapi_tester.clients import OpenAPIClient

    return OpenAPIClient(schema_tester=schema_tester)

如果您使用的是纯 Django 测试框架,我们建议创建自定义测试用例实现,并使用它而不是原始的 Django 实现。

import functools

from django.test.testcases import SimpleTestCase
from openapi_tester.clients import OpenAPIClient
from openapi_tester.schema_tester import SchemaTester

schema_tester = SchemaTester()


class MySimpleTestCase(SimpleTestCase):
    client_class = OpenAPIClient
    # or use `functools.partial` when you want to provide custom
    # ``SchemaTester`` instance:
    # client_class = functools.partial(OpenAPIClient, schema_tester=schema_tester)

这将确保您所有新实现的观点都将与 OpenAPI 模式进行验证。

已知问题

  • 我们使用 prance 作为模式解析器,它在解析(非常)复杂的 OpenAPI 2.0 模式方面有一些问题。如果您遇到问题,请在此处记录它们

贡献

欢迎贡献。请参阅 贡献指南

项目详细信息


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

drf_openapi_tester-2.3.3.tar.gz (19.2 kB 查看哈希值)

上传时间

构建分布

drf_openapi_tester-2.3.3-py3-none-any.whl (20.0 kB 查看哈希值)

上传时间 Python 3

支持者