Как стать автором
Обновить

Измерение покрытия API тестами на основе Swagger для Python

Время на прочтение11 мин
Количество просмотров2.8K
Overview
Overview

Вступление

В этой статье хочу рассказать про инструмент swagger-coverage-tool — решение для автоматического измерения покрытия API автотестами на Python.

Основная цель инструмента — определить, насколько полно тесты покрывают API-контракт, представленный в формате Swagger (OpenAPI). Здесь ключевые слова — "автоматически" и "на основе бизнес-требований". Ведь если измерить покрытие кода — задача давно решённая (во многих языках такие инструменты встроены из коробки), то вот получить представление о бизнес-покрытии (что именно из спецификации API проверено) — задача куда менее тривиальная.

swagger-coverage-tool поддерживает библиотеки httpx и requests — два наиболее популярных клиента для работы с HTTP в Python. Благодаря этому инструмент легко внедряется в существующие проекты без необходимости менять инфраструктуру тестов.

Этот инструмент родился как продолжение идеи, заложенной в моём предыдущем проекте — tests-coverage-tool для покрытия gRPC-контрактов. Он отлично зарекомендовал себя в реальных проектах: позволил оперативно выявлять непокрытые участки API, экономя время и снижая риски. Именно его успех стал причиной создания нового инструмента — swagger-coverage-tool, но уже для HTTP API на основе Swagger.

Что измеряет инструмент?

Важно понимать, что оба инструмента — swagger-coverage-tool и tests-coverage-tool — оценивают покрытие именно контрактов, а не всей бизнес-логики или условий. Это означает:

  • Проверяется, какие эндпоинты, методы, query-параметры, запросы/ответы и статус-коды из спецификации реально вызываются в тестах;

  • Инструмент не требует анализа кода, а лишь фиксирует факт обращения к определённой части API.

Простота использования

Одна из ключевых задач при создании этих инструментов — максимальная простота интеграции. Всё, что нужно:

  1. Установить библиотеку;

  2. Подключить декоратор;

  3. Указать путь к Swagger-контракту.

Дальше инструмент начинает автоматически собирать данные о вызовах и сохранять информацию о покрытии. По завершению тестов можно сгенерировать HTML или JSON отчёт. Причём HTML-отчёт формируется как единый .html-файл, который можно открыть в браузере без дополнительного хостинга или зависимостей — всё встроено прямо внутрь.

Концепция

Основная идея swagger-coverage-tool — сравнивать фактическое покрытие API автотестами с актуальной Swagger-документацией.

Каждый раз при вызове API (то есть при выполнении HTTP-запроса) инструмент автоматически сохраняет информацию о покрытии в простом и наглядном формате:

{
  "name": "/api/v1/courses/{course_id}",
  "method": "GET",
  "service": "api-course-service",
  "status_code": 200,
  "query_parameters": [
    "userId"
  ],
  "is_request_covered": false,
  "is_response_covered": true
}

Что именно сохраняется:

  • Имя эндпоинта — путь запроса (например, /api/v1/courses/{course_id}). Этот путь должен точно соответствовать спецификации в Swagger-документации.

  • HTTP-метод — тип запроса: GET, POST, PATCH и т.д.

  • Название сервиса — используется для того, чтобы можно было измерять покрытие отдельно для каждого сервиса. Это особенно важно в микросервисной архитектуре, где у каждого сервиса свой Swagger. При этом, если вы работаете только с одним сервисом, всё также будет корректно.

  • Статус-код ответа — позволяет оценить, какие именно коды были покрыты тестами (200, 400, 404, и т.д.).

  • Статус покрытия запроса и ответа — инструмент определяет, присутствовали ли тело запроса и/или ответ в обращении к эндпоинту.

  • Query-параметры — также фиксируются query-параметры, переданные в URL.

Что даёт измерение покрытия?

Инструмент позволяет получить:

  • Общее покрытие API автотестами по каждому сервису;

  • Покрытие по эндпоинтам — какие именно вызваны, какими методами и сколько раз;

  • Покрытие по статус-кодам — можно понять, какие варианты ответа были протестированы;

  • Покрытие по query-параметрам — особенно полезно при анализе покрытия тех эндпоинтов, где доступно множество фильтров через строку запроса — например, при реализации поисковых функций.

  • Покрытие запроса/ответа — позволяет убедиться, что если эндпоинт принимает данные (например, через тело запроса) и возвращает ответ, то оба направления взаимодействия действительно были протестированы — то есть запрос был отправлен, а ответ получен.

  • Историю покрытия — сохраняется динамика, можно отследить, как покрытие менялось со временем.

Почему это лучше, чем альтернативы?

Инструмент swagger-coverage-tool предлагает подход, который гораздо надёжнее и удобнее, чем многие существующие способы "ручного" измерения:

  • Лучше, чем делать это вручную. Обычно при попытке как-то измерить покрытие — создаются таблицы, mind-map схемы, dashboard-ы в TMS и прочая документация. Она быстро устаревает и теряет актуальность. Здесь же покрытие фиксируется автоматически, без дополнительной рутины.

  • Лучше, чем не измерять вообще. Типичная ситуация — "у нас всё покрыто тестами". Но как только запускаешь инструмент и смотришь на реальный отчёт — становится очевидно, сколько важных вещей на самом деле не покрыто. И это часто очень сильно отличается от ожиданий команды.

  • Лучше, чем просто покрытие кода. Кодовое покрытие важно, но оно не даёт понимания, какие именно бизнес-сценарии реально тестируются. Кроме того, цифры вроде "покрытие 87%" не всегда понятны аналитикам, тестировщикам или менеджерам. А вот отчет, где явно указано, какие методы и эндпоинты покрыты — уже гораздо нагляднее и доступнее.

Установка

Прежде чем начать работу с swagger-coverage-tool, необходимо установить библиотеку:

pip install swagger-coverage-tool

После установки вы можете использовать библиотеку как в коде, так и через CLI-интерфейс (Command Line Interface).

Импорт в коде

from swagger_coverage_tool import get_settings, SwaggerCoverageTracker

CLI-интерфейс

Вместе с установкой становится доступна команда:

swagger-coverage-tool --help

Библиотека поставляется с максимально простым CLI — всего две основные команды:

  • Генерация отчёта. swagger-coverage-tool save-report — эта команда собирает все накопленные данные покрытия и генерирует HTML и JSON-отчёты. HTML-отчёт — это один самодостаточный файл, который можно открыть в любом браузере и сразу увидеть результат.

  • Просмотр конфигурации. swagger-coverage-tool print-config — позволяет вывести текущую конфигурацию в консоль. Полезно, если нужно убедиться, что конфиги подтянулись корректно и всё работает как надо.

Настройки

Для корректной работы swagger-coverage-tool необходимо указать настройки. Библиотека поддерживает несколько способов конфигурации:

  • .env файл — для объявления через переменные окружения. Пример .env

  • swagger_coverage_config.yaml — конфигурация в YAML-файле. Пример YAML

  • swagger_coverage_config.json — конфигурация в JSON-файле. Пример JSON

Все способы работают аналогично, формат просто выбирается под ваш проект. Ниже рассмотрим пример в формате YAML.

Пример swagger_coverage_config.yaml

services:
  - key: "my-api-service"  # (обязательно) Уникальный ключ сервиса
    name: "My API Service"  # (обязательно) Название сервиса, отображается в отчёте
    tags: [ "API", "PRODUCTION" ]  # (опционально) Метки для фильтрации/группировки
    repository: "https://github.com/my-api"  # (опционально) Ссылка на репозиторий с кодом
    swagger_url: "https://my-api.com/swagger.json"  # (обязательно, если не указан swagger_file) Ссылка на swagger JSON файл
    # swagger_file: "swagger_file_path.json"  # (альтернатива swagger_url) Локальный путь к swagger JSON

results_dir: "./coverage-results"  # (опционально) Папка, куда сохраняются временные результаты покрытия

history_file: "./coverage-history.json"  # (опционально) Путь к файлу с историей покрытия
history_retention_limit: 30  # (опционально) Количество последних записей истории, которые нужно сохранять

html_report_file: "./index.html"  # (опционально) Путь к итоговому HTML-отчёту
json_report_file: "./coverage-report.json"  # (опционально) Путь к итоговому JSON-отчёту

Что важно знать:

  • servicesэто единственное обязательное поле. Остальные настройки являются опциональными.

  • Можно указать либо swagger_url, либо swagger_file, но хотя бы один из них должен быть указан для каждого сервиса.

  • Если вы не хотите генерировать какой-либо из отчетов, просто передайте null. Например: html_report_file: null или json_report_file: null

  • Конфигурационный файл должен находиться в корне проекта или в директории, откуда запускается CLI/тесты.

  • Библиотека работает как с Swagger v2, так и с OpenAPI v3. Важно указывать путь именно на JSON файл, а не на Swagger UI. Это может быть либо URL, либо путь к локальному файлу.

Если базовые настройки заданы — библиотека готова к использованию, и можно начинать собирать покрытие.

Использование

Использование swagger-coverage-tool максимально простое и интуитивное. Ниже приведён пример для библиотеки httpx, которая используется для выполнения HTTP-запросов в Python.

import httpx

from swagger_coverage_tool import SwaggerCoverageTracker

# Создаём трекер покрытия для сервиса "api-service"
tracker = SwaggerCoverageTracker(service="api-service")


# Отслеживаем GET-запрос на эндпоинт /api/v1/users/{user_id}
@tracker.track_coverage_httpx("/api/v1/users/{user_id}")
def get_user(user_id: str):
    # Выполняем GET-запрос к API
    return httpx.get(f"http://localhost:8000/api/v1/users/{user_id}")


# Отслеживаем POST-запрос на эндпоинт /api/v1/users
@tracker.track_coverage_httpx("/api/v1/users")
def create_user():
    # Выполняем POST-запрос к API
    return httpx.post("http://localhost:8000/api/v1/users")


# Выполняем вызовы функций (эмулируем работу автотестов)
get_user("123")
create_user()
  • SwaggerCoverageTracker — основной объект, через который происходит сбор покрытия.

    • Параметр service указывает ключ сервиса (должен совпадать с ключом в конфиге).

  • @tracker.track_coverage_httpx(...) — декоратор, который:

    • автоматически сохраняет информацию о вызванном эндпоинте;

    • подходит только для функций, возвращающих httpx.Response или requests.Response;

    • фиксирует метод, URL, query-параметры, запрос/ответ и статус-код из ответа;

    • сохраняет результат в папку coverage-results (по умолчанию, можно изменить в конфиге).

  • Аргумент в декораторе (/api/v1/users/{user_id}) должен точно соответствовать пути в Swagger-документации, включая параметры ({user_id}).

Использование с несколькими сервисами

Если у вас микросервисная архитектура, вы можете создать отдельный трекер на каждый сервис. Например:

user_service_tracker = SwaggerCoverageTracker(service="user-service")
account_service_tracker = SwaggerCoverageTracker(service="account-service")

И для каждого трекера использовать свой декоратор @user_service_tracker.track_coverage_httpx(...)

После вызова API

После вызова всех функций (например, в процессе выполнения автотестов):

  • Для каждого запроса будет сохранён результат покрытия в папку ./coverage-results.

  • Файлы сохраняются по одному на каждый вызов — удобно для анализа и агрегации.

  • После завершения всех тестов можно будет сгенерировать финальный отчёт.

Отчет

После запуска тестов инструмент автоматически соберет данные о покрытии и сохранит их в папку coverage-results. Эти данные будут использованы для генерации отчетов, которые можно сохранить в разных форматах. Чтобы создать отчет, необходимо выполнить команду:

swagger-coverage-tool save-report

Команда save-report генерирует несколько файлов:

  1. index.html — HTML отчет в виде единого файла. Этот файл можно открыть в браузере, опубликовать на платформе GitHub Pages, GitLab Pages или просто поделиться с коллегами. Пример HTML отчета.

  2. coverage-report.json — JSON отчет, содержащий все данные о покрытии. Этот файл можно использовать, например, для вывода краткой информации о покрытии в консоль или для загрузки в сторонние системы.

  3. coverage-history.json — Файл для сохранения истории покрытия. Если вам нужно отслеживать изменения покрытия с течением времени, то при следующем запуске отчета этот файл должен быть доступен. Он не должен модифицироваться вручную — все изменения в нем происходят автоматически через инструмент. При этом файл истории можно разместить в любом месте, просто укажите путь к нему в настройке history_file.

Детали HTML отчета

HTML отчет представляет собой информативный инструмент для анализа покрытия API. Он состоит из нескольких основных секций:

Summary
Summary

В верхней части отчета отображается виджет Config, который показывает параметры конфигурации, используемые при генерации отчета. Здесь можно увидеть:

  • Ссылку на репозиторий сервиса.

  • Ссылку на swagger контракт или путь к файлу, который был использован для загрузки swagger схемы.

Вы можете выбрать сервис для которого отображается покрытие, нажав на иконку шестеренки в верхнем правом углу отчета. В появившемся модальном окне будет предложено переключиться между различными сервисами:

Settings
Settings

Следующий виджет, Total Service Coverage History, отображает историю покрытия всего сервиса. Это позволит увидеть, как изменялось покрытие с течением времени. Например, если вчера покрытие было на уровне 33%, а сегодня — 77%, то это будет наглядно отображено.

Total Service Coverage — виджет, который показывает текущее покрытие API сервиса. Это позволяет быстро оценить, насколько эффективно покрыт весь сервис целиком

Далее отчет включает таблицу с полным списком эндпоинтов, которые были зафиксированы в swagger контракте:

Endpoints
Endpoints
  • Название эндпоинта и HTTP метод — для каждого эндпоинта отображается его имя и метод (например, GET /api/v1/users).

  • Покрытие эндпоинта — отображается, был ли эндпоинт покрыт тестами (то есть был ли хотя бы один вызов этого эндпоинта). Это позволяет увидеть, какие эндпоинты требуют дополнительного внимания.

  • Количество вызовов эндпоинта — показывает, сколько раз был вызван тот или иной эндпоинт, что помогает определить, какие эндпоинты проверяются чаще.

  • Процент покрытия — отображается процент покрытия для каждого эндпоинта. Покрытие считается по принципу, если для всех статус-кодов (например, 200 и 400) указано, что они должны быть покрыты. Если покрыт только один статус-код, то процент покрытия будет 50%.

Можем посмотреть более подробную информацию о покрытии конкретного эндпоинта:

Details
Details
  • Отображается та же информация, что и в общей таблице с эндпоинтами, но с рядом полезных дополнений. Например, показывается статус покрытия тела запроса — был ли отправлен непустой запрос. На скриншоте выше можно увидеть синюю иконку, которая означает, что эндпоинт не принимает тело запроса (это характерно, например, для GET-запросов).

  • Общее покрытие эндпоинта (total coverage) рассчитывается на основе следующих компонентов: тела запроса, возможных ответов, статус-кодов и query-параметров. Таким образом, инструмент предоставляет максимально объективную оценку того, насколько полно покрыт конкретный эндпоинт, что позволяет легко выявить слабые места.

  • Query-параметры — в таблице наглядно отображается, какие query-параметры были покрыты. Это особенно важно, когда в эндпоинте реализована сложная фильтрация — например, по user_id, account_id, operation_id, card_id и другое. В таких случаях легко забыть протестировать какой-либо параметр, что может привести к незамеченным ошибкам.

  • Статус-коды — отображается, какие статус-коды были покрыты для данного эндпоинта (например, 200 или 404), а также сколько раз они были получены при тестировании.

  • Ответы — для каждого статус-кода предусмотрено соответствующее тело ответа. Инструмент swagger-coverage-tool проверяет, что по каждому статус-коду действительно был получен ответ с содержимым. Это также отображается в таблице, что позволяет легко обнаружить, если какой-то ответ отсутствует или не был проверен.

  • История покрытия — для каждого эндпоинта сохраняется своя история покрытия, что позволяет проследить изменения покрытия по каждому конкретному эндпоинту, аналогично истории для всего сервиса.

Ну и для полного счастья — доступна тёмная тема:

Dark mode
Dark mode

Отчет, сгенерированный инструментом, предоставляет все необходимые данные для оценки того, какие части API покрыты тестами, а какие требуют внимания. Он наглядно показывает:

  • Общее покрытие всего сервиса.

  • Покрытие по каждому эндпоинту.

  • Историю покрытия и изменение показателей с течением времени.

С помощью этого отчета можно легко определить области, требующие дополнительных тестов, и улучшить качество покрытия вашего API.

Заключение

В итоге, swagger-coverage-tool — это максимально простой и легковесный инструмент для измерения покрытия API автотестами. Он не требует сложной настройки, не накладывает дополнительного оверхеда и легко встраивается в существующую инфраструктуру тестирования. Основное его преимущество — автоматическое измерение покрытия, без необходимости делать что-либо вручную.

Несмотря на простоту, инструмент уже сейчас предоставляет всё необходимое для объективной оценки того, какие части API покрыты тестами, а какие — нет. Это помогает вовремя выявлять и устранять пробелы в тестировании и, как следствие, снижать риски багов на проде.

Конечно, у swagger-coverage-tool есть потенциал для дальнейшего развития — например, углублённый анализ тела запроса и ответа, работа с параметрами, условиями, валидациями JSON Schema и другое. Но уже сейчас инструмент выполняет свою основную задачу — даёт прозрачную картину покрытия API на основе контрактов (Swagger/OpenAPI).

Рекомендую попробовать swagger-coverage-tool в своём проекте. Это не потребует много времени, но даже в базовой конфигурации вы сможете получить полезную аналитику и, возможно, откроете для себя те части API, которые ранее оставались без внимания.

Минимум — это интересный опыт. Максимум — реальное повышение качества вашего API.

Весь исходный код инструмента вы можете найти на моем GitHub:

Теги:
Хабы:
+23
Комментарии0

Публикации

Работа

Ближайшие события