Недавно у меня была возможность создать фляжное приложение с разными маршрутами и выполнить его модульное тестирование. Я делюсь тем, что узнал здесь, в надежде, что это будет полезно другим разработчикам. Я собираюсь поделиться парой маршрутов приложений фляг, а затем рассказать, как я их тестировал.
Это упрощенный фрагмент моего кода, который использует библиотеку flask (импортированную вверху) и содержит два метода: один для маршрута «/» и один для маршрута «/about». Внизу также есть основной метод, который запускает приложение фляги.
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def home_page(): return render_template("index.html") @app.route("/about") def about_page(): return render_template("about.html") if __name__ == "__main__": app.run(debug=False, host="0.0.0.0", port="5000")
Вот как я тестировал эти два метода с помощью pytest:
import pytest from pytest_mock import MockFixture @pytest.fixture def client(): app.config.update({"TESTING": True}) with app.test_client() as client: yield client def test_homepage(client): response = client.get("/") assert response.status_code == 200 assert b"Welcome to the home page" in response.data def test_about_page(client): response = client.get("/about") assert response.status_code == 200 assert b"I am a software engineer" in response.data
Во-первых, мы создаем метод client(), который нам нужен, чтобы иметь возможность делать запросы к приложению, не запуская настоящий работающий сервер.
Чтобы проверить, что приведенный ниже код
@app.route("/") def home_page(): return render_template("index.html")
делает то, что мы думаем, мы вызываем client.get() и передаем тестируемый маршрут в качестве аргумента методу get().
def test_homepage(client): response = client.get("/")
Вот и все, что касается настройки модульного теста. Это очень просто, так как тестируется только один маршрут.
Затем мы переходим к утверждению, что мы получаем 200 от тестового сервера, что имитирует реальную вещь (то есть успешный вызов маршрута!).
assert response.status_code == 200
Наше последнее утверждение состоит в том, что то, что мы знаем, будет в ответе (то, что мы получим от сервера). В этом примере я знаю, что «Добро пожаловать на домашнюю страницу» должно быть в html маршрута «/» (поскольку в этом случае маршрут возвращает статическую страницу). Поэтому я проверяю, находится ли он в response.data.
assert b"Welcome to the home page" in response.data
Откуда взялись response.data? Это одно из многих свойств объекта ответа. Вызов .data в ответе позволяет нам увидеть ответ в виде байтов. Вот почему мы преобразуем строку b"Добро пожаловать на домашнюю страницу" в байтовый объект.
Это простой домашний маршрут.
Как насчет маршрута /about flask?
@app.route("/about") def about_page(): return render_template("about.html")
Шаблон для модульного теста точно такой же — мы просто добавляем соответствующий маршрут:
def test_about_page(client): response = client.get("/about") assert response.status_code == 200 assert b"I am a software engineer" in response.data
Вам может быть интересно, почему мы не тестируем метод render_template(), который использует наш код. Это потому, что это встроенный метод библиотеки flask, а не тот, который мы написали сами.
Спасибо за чтение, я надеюсь, что это было полезно!
Официальные документы: https://flask.palletsprojects.com/en/2.3.x/testing/#sending-requests-with-the-test-client