Тестирование модулей Flask с использованием Pytest и Coverage

Beginner

This tutorial is from open-source community. Access the source code

Введение

В этом практическом занятии мы научимся писать юнит-тесты для веб-приложения на 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. Эти инструменты помогают нам убедиться, что наше приложение работает как ожидается, и выявить области, требующие улучшения. Писание тестов для своего кода - хороший практик, так как это позволяет вам обнаруживать ошибки, пока они не превратятся в проблему.