
Вступление
В этой статье хочу рассказать про инструмент 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.
Простота использования
Одна из ключевых задач при создании этих инструментов — максимальная простота интеграции. Всё, что нужно:
Дальше инструмент начинает автоматически собирать данные о вызовах и сохранять информацию о покрытии. По завершению тестов можно сгенерировать 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
файл — для объявления через переменные окружения. Пример .envswagger_coverage_config.yaml
— конфигурация в YAML-файле. Пример YAMLswagger_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
генерирует несколько файлов:
index.html
— HTML отчет в виде единого файла. Этот файл можно открыть в браузере, опубликовать на платформе GitHub Pages, GitLab Pages или просто поделиться с коллегами. Пример HTML отчета.coverage-report.json
— JSON отчет, содержащий все данные о покрытии. Этот файл можно использовать, например, для вывода краткой информации о покрытии в консоль или для загрузки в сторонние системы.coverage-history.json
— Файл для сохранения истории покрытия. Если вам нужно отслеживать изменения покрытия с течением времени, то при следующем запуске отчета этот файл должен быть доступен. Он не должен модифицироваться вручную — все изменения в нем происходят автоматически через инструмент. При этом файл истории можно разместить в любом месте, просто укажите путь к нему в настройкеhistory_file
.
Детали HTML отчета
HTML отчет представляет собой информативный инструмент для анализа покрытия API. Он состоит из нескольких основных секций:

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

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

Название эндпоинта и HTTP метод — для каждого эндпоинта отображается его имя и метод (например, GET
/api/v1/users
).Покрытие эндпоинта — отображается, был ли эндпоинт покрыт тестами (то есть был ли хотя бы один вызов этого эндпоинта). Это позволяет увидеть, какие эндпоинты требуют дополнительного внимания.
Количество вызовов эндпоинта — показывает, сколько раз был вызван тот или иной эндпоинт, что помогает определить, какие эндпоинты проверяются чаще.
Процент покрытия — отображается процент покрытия для каждого эндпоинта. Покрытие считается по принципу, если для всех статус-кодов (например, 200 и 400) указано, что они должны быть покрыты. Если покрыт только один статус-код, то процент покрытия будет 50%.
Можем посмотреть более подробную информацию о покрытии конкретного эндпоинта:

Отображается та же информация, что и в общей таблице с эндпоинтами, но с рядом полезных дополнений. Например, показывается статус покрытия тела запроса — был ли отправлен непустой запрос. На скриншоте выше можно увидеть синюю иконку, которая означает, что эндпоинт не принимает тело запроса (это характерно, например, для GET-запросов).
Общее покрытие эндпоинта (
total coverage
) рассчитывается на основе следующих компонентов: тела запроса, возможных ответов, статус-кодов и query-параметров. Таким образом, инструмент предоставляет максимально объективную оценку того, насколько полно покрыт конкретный эндпоинт, что позволяет легко выявить слабые места.Query-параметры — в таблице наглядно отображается, какие query-параметры были покрыты. Это особенно важно, когда в эндпоинте реализована сложная фильтрация — например, по
user_id
,account_id
,operation_id
,card_id
и другое. В таких случаях легко забыть протестировать какой-либо параметр, что может привести к незамеченным ошибкам.Статус-коды — отображается, какие статус-коды были покрыты для данного эндпоинта (например, 200 или 404), а также сколько раз они были получены при тестировании.
Ответы — для каждого статус-кода предусмотрено соответствующее тело ответа. Инструмент
swagger-coverage-tool
проверяет, что по каждому статус-коду действительно был получен ответ с содержимым. Это также отображается в таблице, что позволяет легко обнаружить, если какой-то ответ отсутствует или не был проверен.История покрытия — для каждого эндпоинта сохраняется своя история покрытия, что позволяет проследить изменения покрытия по каждому конкретному эндпоинту, аналогично истории для всего сервиса.
Ну и для полного счастья — доступна тёмная тема:

Отчет, сгенерированный инструментом, предоставляет все необходимые данные для оценки того, какие части API покрыты тестами, а какие требуют внимания. Он наглядно показывает:
Общее покрытие всего сервиса.
Покрытие по каждому эндпоинту.
Историю покрытия и изменение показателей с течением времени.
С помощью этого отчета можно легко определить области, требующие дополнительных тестов, и улучшить качество покрытия вашего API.
Заключение
В итоге, swagger-coverage-tool — это максимально простой и легковесный инструмент для измерения покрытия API автотестами. Он не требует сложной настройки, не накладывает дополнительного оверхеда и легко встраивается в существующую инфраструктуру тестирования. Основное его преимущество — автоматическое измерение покрытия, без необходимости делать что-либо вручную.
Несмотря на простоту, инструмент уже сейчас предоставляет всё необходимое для объективной оценки того, какие части API покрыты тестами, а какие — нет. Это помогает вовремя выявлять и устранять пробелы в тестировании и, как следствие, снижать риски багов на проде.
Конечно, у swagger-coverage-tool есть потенциал для дальнейшего развития — например, углублённый анализ тела запроса и ответа, работа с параметрами, условиями, валидациями JSON Schema и другое. Но уже сейчас инструмент выполняет свою основную задачу — даёт прозрачную картину покрытия API на основе контрактов (Swagger/OpenAPI).
Рекомендую попробовать swagger-coverage-tool в своём проекте. Это не потребует много времени, но даже в базовой конфигурации вы сможете получить полезную аналитику и, возможно, откроете для себя те части API, которые ранее оставались без внимания.
Минимум — это интересный опыт. Максимум — реальное повышение качества вашего API.
Весь исходный код инструмента вы можете найти на моем GitHub: