Testes Unitários Flask com Pytest e Coverage

Beginner

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

Introdução

Neste laboratório, aprenderemos como escrever testes unitários para uma aplicação Flask. Usaremos pytest e coverage para testar e medir nosso código. Ao final deste laboratório, você entenderá como garantir que sua aplicação funcione como esperado e identificar áreas que precisam de melhorias.

Nota: Você precisa criar o arquivo de código você mesmo e executá-lo no ambiente. Você pode visualizar o status do serviço Flask na Web 5000.

Instalar Pytest e Coverage

Primeiramente, precisamos instalar pytest e coverage. Estas são ferramentas de teste e medição de código, respectivamente. Execute o seguinte comando no seu terminal para instalar:

pip install pytest coverage

Configuração e Fixtures

Em seguida, configuraremos as fixtures de teste em um arquivo chamado conftest.py. Uma fixture é uma função que é executada antes de cada função de teste à qual ela é aplicada.

Nesta etapa, criaremos um banco de dados temporário e o preencheremos com alguns dados para teste.

Aqui está o código a ser adicionado em 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()

Escrever Testes para a Factory

Em seguida, escreveremos testes para a função factory, que é responsável por criar a aplicação Flask. Estes testes garantem que a aplicação se comporte como esperado com base na configuração passada para ela.

Aqui está o código a ser adicionado em 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!'

Testar a Conexão ao Banco de Dados

Após testar a factory, testaremos a conexão ao banco de dados. Estes testes garantem que a conexão ao banco de dados seja estabelecida e fechada conforme o esperado.

Aqui está o código a ser adicionado em 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)

Testar a Autenticação

Em seguida, escreveremos testes para a autenticação do usuário. Estes testes garantem que os usuários podem fazer login e logout conforme o esperado, e que as mensagens de erro apropriadas são exibidas quando necessário.

Aqui está o código a ser adicionado em 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'

Testar as Publicações do Blog

Finalmente, escreveremos testes para as publicações do blog. Estes testes garantem que os usuários podem criar, atualizar e excluir publicações do blog conforme o esperado.

Aqui está o código a ser adicionado em 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

Executar os Testes

Agora que escrevemos nossos testes, podemos executá-los usando o comando pytest:

pytest

Para medir a cobertura de código (code coverage) dos seus testes, use o comando coverage para executar o pytest:

coverage run -m pytest

Você pode visualizar um relatório de cobertura simples no terminal com o seguinte comando:

coverage report

Resumo

Neste laboratório, aprendemos como escrever testes unitários para uma aplicação Flask usando pytest e coverage. Essas ferramentas nos ajudam a garantir que nossa aplicação funcione como esperado e a identificar áreas que precisam de melhorias. Escrever testes para o seu código é uma boa prática, pois ajuda a detectar bugs antes que eles se tornem um problema.