Введение
В этом практическом занятии мы научимся писать юнит-тесты для веб-приложения на Flask. Мы будем использовать pytest и coverage для тестирования и измерения нашей программы. В конце практического занятия вы поймете, как убедиться, что ваше приложение работает как ожидается, и сможете определить области, требующие улучшения.
Примечание: вам нужно самостоятельно создать файл с кодом и запустить его в среде. Вы можете предварительно просмотреть статус сервиса Flask на порту 5000 в браузере.
Установка pytest и coverage
Во - первых, нам нужно установить pytest и coverage. Эти инструменты используются для тестирования и измерения кода соответственно. Запустите следующую команду в терминале для установки:
pip install pytest coverage
Настройка и фикстуры
Далее, мы настроим тестовые фикстуры в файле с именем conftest.py. Фикстура - это функция, которая выполняется перед каждым тестовым функцией, к которой она применяется.
В этом шаге мы создадим временную базу данных и заполним ее некоторыми данными для тестирования.
Вот код, который нужно добавить в tests/conftest.py:
## tests/conftest.py
import os
import tempfile
import pytest
from flaskr import create_app
from flaskr.db import get_db, init_db
with open(os.path.join(os.path.dirname(__file__), 'data.sql'), 'rb') as f:
_data_sql = f.read().decode('utf8')
@pytest.fixture
def app():
db_fd, db_path = tempfile.mkstemp()
app = create_app({
'TESTING': True,
'DATABASE': db_path,
})
with app.app_context():
init_db()
get_db().executescript(_data_sql)
yield app
os.close(db_fd)
os.unlink(db_path)
@pytest.fixture
def client(app):
return app.test_client()
@pytest.fixture
def runner(app):
return app.test_cli_runner()
Напишите тесты для фабрики
Далее, мы напишем тесты для фабричной функции, которая отвечает за создание веб - приложения Flask. Эти тесты гарантируют, что приложение ведет себя как ожидается в зависимости от конфигурации, переданной в него.
Вот код, который нужно добавить в tests/test_factory.py:
## tests/test_factory.py
from flaskr import create_app
def test_config():
assert not create_app().testing
assert create_app({'TESTING': True}).testing
def test_hello(client):
response = client.get('/hello')
assert response.data == b'Hello, World!'
Тестирование соединения с базой данных
После тестирования фабрики мы проверим соединение с базой данных. Эти тесты гарантируют, что соединение с базой данных устанавливается и закрывается как ожидается.
Вот код, который нужно добавить в tests/test_db.py:
## tests/test_db.py
import sqlite3
import pytest
from flaskr.db import get_db
def test_get_close_db(app):
with app.app_context():
db = get_db()
assert db is get_db()
with pytest.raises(sqlite3.ProgrammingError) as e:
db.execute('SELECT 1')
assert 'closed' in str(e.value)
Тестирование аутентификации
Далее, мы напишем тесты для аутентификации пользователей. Эти тесты гарантируют, что пользователи могут входить и выходить из системы как ожидается, и что при необходимости отображаются соответствующие сообщения об ошибках.
Вот код, который нужно добавить в tests/test_auth.py:
## tests/test_auth.py
import pytest
from flask import g, session
from flaskr.db import get_db
def test_login(client, auth):
assert client.get('/auth/login').status_code == 200
response = auth.login()
assert response.headers["Location"] == "/"
with client:
client.get('/')
assert session['user_id'] == 1
assert g.user['username'] == 'test'
Тестирование блоговых постов
Наконец, мы напишем тесты для блоговых постов. Эти тесты гарантируют, что пользователи могут создавать, обновлять и удалять блоговые посты как ожидается.
Вот код, который нужно добавить в tests/test_blog.py:
## tests/test_blog.py
import pytest
from flaskr.db import get_db
def test_create(client, auth, app):
auth.login()
assert client.get('/create').status_code == 200
client.post('/create', data={'title': 'created', 'body': ''})
with app.app_context():
db = get_db()
count = db.execute('SELECT COUNT(id) FROM post').fetchone()[0]
assert count == 2
Запустите тесты
Теперь, когда мы написали наши тесты, мы можем запустить их с помощью команды pytest:
pytest
Для измерения покрытия кода тестами используйте команду coverage для запуска pytest:
coverage run -m pytest
Вы можете просмотреть простой отчет о покрытии в терминале с помощью следующей команды:
coverage report
Резюме
В этом практическом занятии мы научились писать модульные тесты для веб-приложения на Flask с использованием pytest и coverage. Эти инструменты помогают нам убедиться, что наше приложение работает как ожидается, и выявить области, требующие улучшения. Писание тестов для своего кода - хороший практик, так как это позволяет вам обнаруживать ошибки, пока они не превратятся в проблему.