Введение
Testing является неотъемлемой частью процесса разработки программного обеспечения, он обеспечивает то, что код ведет себя как ожидается и free of defects. В Python pytest
является популярным фреймворком для тестирования, предлагающим несколько преимуществ по сравнению с стандартным модулем unit test
, который является встроенным модулем тестирования Python и входит в стандартную библиотеку. pytest
включает более простой синтаксис, лучший вывод, мощные данные задачи и богатую экосистему плагинов. Это руководство вам поможет пройти процесс настройки приложения Flask, интегрировать данные задачи pytest
и написать единичные тесты с использованием pytest
.
Предупреждения
Перед началом вам потребуется следующее:
-
Сервер с установленной системой Ubuntu и пользователь не-root, имеющий права sudo и активную firewall. Чтобы получить инструкции по установке, пожалуйста выберите из этого списка вашу дистрибуцию и следуйте指南 настройки начального сервера. Пожалуйста, убедитесь, что работаете с поддерживаемой версией Ubuntu.
-
Освоенность с использованием командной строки Linux. Вы можете ознакомиться с информацией в этой guide on Linux command line primer.
-
Основное понимание Python программирования и тестирования с использованием фреймворка
pytest
в Python. Чтобы перейти к дополнительным сведениям оpytest
, вы можете обратиться к нашему учебнику по PyTest Python Testing Framework. -
Python 3.7 или более новая версия установлена на вашей системе Ubuntu. Чтобы узнать, как запускать сценарий Python на Ubuntu, вы можете прочитать нашу статью Как запустить сценарий Python на Ubuntu.
Почему pytest
является лучшей альтернативой unittest
pytest
предлагает несколько преимуществ над встроенным фреймворком unittest
:
-
Pytest позволяет вам писать тесты с меньшим количеством шаблонного кода, используя простые операторы assert вместо более развёрнутых методов, требуемых
unittest
. -
Он обеспечивает более детальные и читабельные выводы, что помогает легче определить, где и почему тест не сработал.
-
Фикшены Pytest позволяют работать с более гибкими и реusable тестовыми установками, чем методы
setUp
иtearDown
unittest. -
Он упрощает запуск того же тестового функции с несколькими наборами входных данных, что не так просто в
unittest
. -
Pytest имеет обширное собрание плагинов, которые extends его функциональность, от инструментов охвата кода до параллельного выполнения тестов.
-
Он автоматически обнаруживает тестовые файлы и функции, соответствующие его наименованиям, экономя вам время и усилия в управлении наборами тестов.
Давая такие преимущества, pytest
часто является предпочтительным выбором для современного тестирования на Python. Давайте настроим приложение Flask и напишем модульные тесты, используя pytest
.
Шаг 1 – Настройка среды
Ubuntu 24.04 по умолчанию идет с Python 3. Откройте терминал и выполните следующую команду, чтобы удостовериться в установке Python 3:
Если Python 3 уже установлен на вашей машине, вышеуказанная команда вернет текущую версию установленного Python 3. Если он не установлен, вы можете выполнить следующую команду и установить Python 3:
Далее вам нужно установить установщик пакетов pip
в вашей системе:
Как только pip
установлен, давайте установим Flask.
Шаг 2 – Создание приложения Flask
Начнем с создания простого приложения Flask. Создайте новую директорию для вашего проекта и переместитесь в нее:
Теперь создадим и активируем виртуальную среду для управления зависимостями:
Установим Flask с использованием pip
:
Теперь создадим простую Flask-апликацию. Создайте новый файл с именем app.py
и добавьте следующий код:
Эта апликация имеет три маршрута:
/
: возвращает простое сообщение “Привет, Flask!”./about
: возвращает простое сообщение “Это страница о проекте”./multiply/<int:x>/<int:y>
: умножает два целых числа и возвращает результат.
Чтобы запустить приложение, выполните следующий приказ:
Согласно вышенапечатанному выводу вы можете заметить, что сервер запущен на http://127.0.0.1
и принимает соединения на порту 5000
. Откройте другой консоль Ubuntu и выполните нижеследующий curl
запрос один за другим:
- GET:
curl http://127.0.0.1:5000/
- GET:
curl http://127.0.0.1:5000/about
- GET:
curl http://127.0.0.1:5000/multiply/10/20
Давайте посмотрим, что делают эти GET-запросы:
-
curl http://127.0.0.1:5000/
:
Это отправляет GET-запрос на корневую URL (‘/’) нашего Flask-приложения. Сервер отвечает JSON-объектом с сообщением “Hello, Flask!”, демонстрируя базовую функциональность нашего домашнего маршрута. -
curl http://127.0.0.1:5000/about
:
Это отправляет GET-запрос на маршрут/about
. Сервер отвечает JSON-объектом с сообщением “This is the About page”. Это показывает, что наш маршрут работает корректно. -
curl http://127.0.0.1:5000/multiply/10/20
:
Это отправляет GET-запрос на маршрут/multiply
с двумя параметрами: 10 и 20. Сервер умножает эти числа и отвечает JSON-объектом с результатом (200). Это демонстрирует, что наш маршрут для умножения правильно обрабатывает URL-параметры и выполняет вычисления.
Эти GET
-запросы позволяют нам взаимодействовать с API-конечными точками нашего Flask-приложения, получая информацию или вызывая действия на сервере без изменения данных. Их используют для извлечения данных, тестирования функциionalности концептных точек и проверки, что наши маршруты отвечают ожидаемо.
Посмотрим на действие каждого из этих GET
-запросов:
Шаг 3 – Установка pytest
и написание первого теста
Теперь, когда у вас есть базовое Flask-приложение, установим pytest
и напишем несколько модульных тестов.
Установите pytest
с помощью pip
:
Создайте каталог tests для хранения ваших тестовых файлов:
Теперь создадим новый файл с именем test_app.py
и добавим следующий код:
Давайте посмотрим на функции в этом тестовом файле:
-
@pytest.fixture def client()
:
Это fixtures pytest, который создает тестовый клиент для нашей Flask app. Он используетapp.test_client()
метод для создания клиента, который может отправлять запросы в нашу app без запуска реального сервера. СтаEMENTyield
позволяет использовать клиент в тестах и затем правильно закрывать его после каждого теста. -
def test_home(client):
Эта функция тестирует домашнюю роут (
/
) нашего приложения. Она отправляет GET-запрос по этому роуту с помощью тестового клиента, затем утверждает, что статус-код ответа равен 200 (OK) и что JSON-ответ соответствует ожидаемому сообщению. -
def test_about(client):
Подобно
test_home
, эта функция тестирует роут о себе (/about
). Она проверяет наличие статус-кода 200 и проверяет содержимое JSON-ответа. -
def test_multiply(client):
Эта функция тестирует роут умножения с правильными входными данными (
/multiply/3/4
). Она проверяет, что статус-код равен 200, и что JSON-ответ содержит правильный результат умножения. -
def test_multiply_invalid_input(client)
:
Эта функция тестирует маршрут для умножения с неверными данными ввода (multiply/three/four
). Она проверяет, что статус-код ответа равен 404 (Не найдено), что соответствует ожидаемому поведению, когда маршрут не может соответствовать строковому вводу требуемым целочисленными параметрами. -
def test_non_existent_route(client)
:
Эта функция тестирует поведение приложения, когда доступен несуществующий маршрут. Она отправляет GET-запрос на/non-existent
, который не определен в нашем Flask-приложении. Тест утверждает, что статус-код ответа равен 404 (Не найдено), что позволяет убедиться, что наш сервис правильно обрабатывает запросы на не определенные маршруты.
Эти тесты охватывают базовую функциональность нашего Flask-приложения, убеждаясь, что каждый маршрут правильно реагирует на допустимые входные данные и что маршрут умножения соответствующе обрабатывает неверные входные данные. Utilizing pytest
, we can easily run these tests to verify that our app is working as expected.
Шаг 4 – Запуск тестов
Для запуска тестов выполните следующую команду:
по умолчанию, процесс обнаружения pytest
будет рекурсивно искать в текущем каталоге и его подкаталогах файлы, начинающиеся с именем “test_” или заканчивающиеся на “_test”. Тесты, расположенные в этих файлах, затем будут выполнены. Вы должны увидеть вывод, похожий на:
Это указывает, что все тесты успешно прошли.
Шаг 5: Использование fixture в pytest
fixture – это функции, используемые для предоставления данных или ресурсов тестам. Они могут использоваться для установки и демонтажа тестовых средств, загрузки данных или выполнения других операций настройки. В pytest
fixture определяются с помощью декоратора @pytest.fixture
.
Вот как можно улучшить существующий fixture. Обновите fixture клиента, используя логику установки и разрушения:
Данное установка добавляет печатные заявления, чтобы продемонстрировать фазы установки и разрушения в выходе тестов. Эти могут быть заменены на реальный код управления ресурсами, если это необходимо.
Попробуем запустить тесты снова:
Flag -v
увеличивает verbosity, а flag -s
позволяет печатным заявлениям отображаться в консольном выводе.
Вы должны увидеть следующий вывод:
Шаг 6: Добавление теста с ошибкой
Добавим тест с ошибкой в существующий файл теста. Измените файл test_app.py
и добавьте ниже функцию в конце для теста с ошибкой для неверного результата:
Разбираемся с функцией test_multiply_edge_cases
и объясняем, что делает каждая ее часть:
-
Test with zero:
Это тест проверяет, правильно ли функция умножения обрабатывает умножение на нуль. Мы ожидаем, что результат будет 0, когда любое число умножается на нуль. Это важное крайнее значение для тестирования,因為 некоторые реализации могут иметь проблемы с умножением на нуль. -
Test с большими числами:
Этот тест проверяет, whether функция умножения может обрабатывать большие числа без переполнения или проблем с точностью. Мы умножаем два значения в миллион, ожидая результата в один триллион. Этот тест важен, because он проверяет верхние ограничения возможностей функции. Note, что это может потерпеть неудачу, if реализация сервера не умеет обрабатывать большие числа правильно, что может указать на необходимость библиотек с большими числами или другого типа данных. -
Test на намеренное сбой:
Этот тест нарочно установлен, чтобы провалиться. Он проверяет, whether 2 * 3 равно 7, что является неверным. Этот тест направлен на демонстрацию внешнего вида теста при сбое. Это помогает понять, как выглядят проваленные тесты в выводе тестов, which is an essential skill in test-driven development and debugging processes.
При включении这些 крайних случаев и нарочитого провала вы проверяете не только базовую функциональность вашего многочлена маршрута, но также и его поведение в экстремальных условиях и его способности по сообщению ошибок. Этот подход к тестированию помогает обеспечить надежность и устойчивость нашей приложения.
Попробуем запустить тесты снова:
Вы должны увидеть следующий вывод:
Сообщение ошибки, указанное выше, указывает, что тест test_multiply_edge_cases
в файле tests/test_app.py
провалился. SPECIFICALLY, last assert в этой тестовой функции вызвало провал.
Этот нарочитый провал полезен для демонстрации, как сообщаются ошибки в тестах и какая информация предоставляется в сообщениях о провалах. Оно показывает точную строку, где произошел провал, ожидаемые и фактические значения и разница между ними.
В реальных условиях вы бы исправили код, чтобы тест прошел успешно, или настроили тест, если ожидаемый результат был неверным. Однако в этом случае ошибка произвольно установлена для учебных целей.
Заключение
В этом учебнике мы рассмотрели, как настроить тесты модуля для приложения Flask с использованием pytest
, внедрить fixture pytest
и продемонстрировали, как выглядят провалы тестов. Следуя этим шагам, вы можете убедиться, что ваши приложения Flask надежны и поддерживаемые, минимизировав bugs и улучшив качество кода.
Вы можете обратиться к официальной документации Flask и официальной документации Pytest, чтобы перейти на более глубокое знание.
Source:
https://www.digitalocean.com/community/tutorials/unit-test-in-flask