Introdução
Testes são essenciais no processo de desenvolvimento de software, garantindo que o código se comporta como esperado e está livre de defeitos. Em Python, o pytest
é um framework de testes popular que oferece várias vantagens sobre o módulo padrão unit test
, que é um framework de teste embutido do Python e faz parte da biblioteca padrão. O pytest
inclui uma sintaxe simples, melhor saída, ferramentas de fixtures poderosas e um rico ecossistema de plugins. Este tutorial irá guiar você através do processo de configuração de uma aplicação Flask, da integração de ferramentas de fixtures do pytest
e da escrita de testes unitários usando o pytest
.
Pré-requisitos
Antes de começar, você precisará dos seguintes itens:
-
Um servidor rodando Ubuntu e um usuário não-root com privilégios de sudo e uma firewall ativa. Para orientações sobre como configurar isso, por favor escolha sua distribuição do sistema operacional da lista desta lista e siga com o guia de configuração inicial do servidor. Certifique-se de trabalhar com uma versão suportada do Ubuntu.
-
Familiaridade com a linha de comando do Linux. Você pode visitar essa guia sobre primeiro contato com a linha de comando do Linux.
-
Um entendimento básico de programação em Python e do framework de teste
pytest
em Python. Você pode referir-se à nossa tutorial sobre Framework de Teste Python pytest para saber mais sobrepytest
. -
Python 3.7 ou superior instalado no seu sistema Ubuntu. Para aprender a executar um script Python em Ubuntu, você pode referir-se à nossa tutorial sobre Como executar um script Python em Ubuntu.
Porque pytest
é uma Alternativa Melhorado ao unittest
pytest
oferece várias vantagens sobre o framework interno unittest
:
-
Pytest permite que você escreva testes com menos código de configuração, usando simples declarações assert em vez das métodos mais verbosos necessários pelo
unittest
. -
Ele fornece saídas mais detalhadas e legíveis, tornando mais fácil identificar onde e por que um teste falhou.
-
Fixtures de Pytest permitem configurações de teste mais flexíveis e reutilizáveis do que os métodos
setUp
etearDown
de unittest. -
Ele facilita a execução da mesma função de teste com vários conjuntos de entradas, o que não é tão direto em
unittest
. -
Pytest possui uma rica coleção de plugins que extendem suas funcionalidades, desde ferramentas de cobertura de código até execução de testes em paralelo.
-
Ele automaticamente descobre arquivos de teste e funções que correspondem às suas convenções de nomenclatura, economizando tempo e esforço na gerencia de suítes de teste.
Com estes benefícios, o pytest
frequentemente é a escolha preferida para testes em Python moderno. Vamos configurar uma aplicação Flask e escrever testes unitários usando o pytest
.
Passo 1 – Configurando o Ambiente
O Ubuntu 24.04 vem com Python 3 por padrão. Abra o terminal e execute o seguinte comando para verificar a instalação do Python 3:
Se o Python 3 já estiver instalado no seu computador, o comando acima retornará a versão atual da instalação do Python 3. Caso contrário, você pode executar o seguinte comando e obter a instalação do Python 3:
A seguir, você precisará instalar o gerenciador de pacotes pip
no seu sistema:
Uma vez que o pip
estiver instalado, vamos instalar o Flask.
Passo 2 – Criar uma Aplicação Flask
Vamos começar criando uma aplicação Flask simples. Crie um novo diretório para seu projeto e navegue até ele:
Agora, vamos criar e ativar um ambiente virtual para gerenciar dependências:
Instale o Flask usando o pip
:
Agora, vamos criar uma simples aplicação Flask. Crie um novo arquivo chamado app.py
e adicione o seguinte código:
Esta aplicação tem três rotas:
/
: Retorna uma mensagem simples “Hello, Flask!”./about
: Retorna uma mensagem simples “This is the About page”./multiply/<int:x>/<int:y>
: Multiplica dois inteiros e retorna o resultado.
Para executar a aplicação, execute o seguinte comando:
Ao examinar a saída acima, você notará que o servidor está rodando em http://127.0.0.1
e está ouvindo na porta 5000
. Abra outra consola do Ubuntu e execute os comandos curl
abaixo um por um:
- 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
Vamos entender o que as requisições GET fazem:
-
curl http://127.0.0.1:5000/
:
Essa é uma requisição GET enviada para a rota raiz (‘/’) de nossa aplicação Flask. O servidor responde com um objeto JSON que contém a mensagem “Hello, Flask!”, demonstrando a funcionalidade básica da nossa rota inicial. -
curl http://127.0.0.1:5000/about
:
Essa é uma requisição GET enviada para a rota/about
. O servidor responde com um objeto JSON que contém a mensagem “This is the About page”. Isto mostra que nossa rota está funcionando corretamente. -
curl http://127.0.0.1:5000/multiply/10/20
:
Essa é uma requisição GET enviada para a rota/multiply
com dois parâmetros: 10 e 20. O servidor multiplica esses números e responde com um objeto JSON que contém o resultado (200). Isto demonstra que nossa rota de multiplicação pode processar corretamente parâmetros de URL e executar cálculos.
Estas requisições GET
permitem que interajamos com as API dos pontos finais do nosso aplicativo Flask, obtendo informações ou disparando ações no servidor sem modificar dados. Elas são úteis para buscar dados, testar a funcionalidade de pontos finais e verificar se nossas rotas estão respondendo como esperado.
Vamos ver cada uma destas requisições GET
em ação:
Passo 3 – Instalando pytest
e Escrevendo Seu Primeiro Teste
Agora que você tem um aplicativo Flask básico, vamos instalar pytest
e escrever alguns testes unitários.
Instale pytest
usando pip
:
Crie um diretório chamado tests para armazenar seus arquivos de teste:
Agora, vamos criar um novo arquivo chamado test_app.py
e adicionar o seguinte código:
Vamos analisar as funções neste arquivo de teste:
-
@pytest.fixture def client()
:
Esta é uma fábrica de pytest que cria um cliente de teste para nossa aplicação Flask. Ela usa o métodoapp.test_client()
para criar um cliente que pode enviar solicitações para nossa aplicação sem executar o servidor real. A instruçãoyield
permite que o cliente seja usado em testes e, em seguida, fechado corretamente após cada teste. -
def test_home(client)
:
Esta função testa a rota home (/
) do nosso aplicativo. Ela envia uma solicitação GET para a rota usando o cliente de teste, e então verifica se o código de status da resposta é 200 (OK) e se a resposta JSON corresponde à mensagem esperada. -
def test_about(client)
:
Semelhante atest_home
, esta função testa a rota about (/about
). Ela verifica o código de status 200 e valida o conteúdo da resposta JSON. -
def test_multiply(client)
:
Esta função testa a rota de multiplicação com entrada válida (/multiply/3/4
). Ela verifica se o código de status é 200 e se a resposta JSON contém o resultado correto da multiplicação. -
def test_multiply_invalid_input(client)
:
Esta função testa a rota de multiplicar com entrada inválida (multiply/three/four
). Ela verifica se o código de status é 404 (Não Encontrado), o que é o comportamento esperado quando a rota não consegue combinar as entradas de string com os parâmetros inteiros necessários. -
def test_non_existent_route(client)
:
Esta função testa o comportamento do aplicativo quando uma rota não existente é acessada. Ela envia uma solicitação GET para/non-existent
, que não está definida em nosso aplicativo Flask. O teste afirma que o código de status da resposta é 404 (Não Encontrado), garantindo que nosso aplicativo trata corretamente solicitudes a rotas não definidas.
Estes testes cobrem a funcionalidade básica do nosso aplicativo Flask, garantindo que cada rota responda corretamente a entradas válidas e que a rota de multiplicar trata entradas inválidas apropriadamente. Utilizando pytest
, podemos executar esses testes facilmente para verificar se nosso aplicativo está funcionando conforme esperado.
Passo 4 – Executando as Testes
Para executar as testes, execute o seguinte comando:
Por padrão, o processo de descoberta de pytest
irá varrer recursivamente a pasta atual e suas subpastas procurando arquivos que começam com o nome “test_” ou terminam com “_test”. Os testes localizados nestes arquivos serão então executados. Você deveria ver saídas semelhantes a:
Isso indica que todos os testes passaram com sucesso.
Passo 5: Usando Fixtures no pytest
Fixtures são funções que são usadas para fornecer dados ou recursos aos testes. Eles podem ser usados para configurar e desconfigurar ambientes de teste, carregar dados ou realizar outras tarefas de configuração. No pytest
, as fixtures são definidas usando o decorador @pytest.fixture
.
Aqui está como melhorar a fixture existente. Atualize a fixture do cliente para usar lógica de configuração e desconfiguração:
Esta configuração adiciona instruções de impressão para demonstrar as fases de setup e teardown no resultado do teste. Estas podem ser substituídas por código de gerenciamento de recursos reais se necessário.
Vamos tentar executar os testes novamente:
A flag -v
aumenta a verbosidade, e a flag -s
permite que as instruções de impressão sejam exibidas no resultado do console.
Você deve ver o seguinte resultado:
Step 6: Adding a Failure Test Case
Vamos adicionar um caso de teste de falha ao arquivo de teste existente. Modifique o arquivo test_app.py
e adicione a função abaixo no final para um caso de teste de falha com um resultado incorreto:
Vamos analisar a função test_multiply_edge_cases
e explicar o que cada parte faz:
-
Test with zero:
Este teste verifica se a função de multiplicação está corretamente lidando com a multiplicação por zero. Esperamos que o resultado seja 0 quando multiplicamos qualquer número por zero. Esse é um caso de borda importante para testar, porque algumas implementações podem ter problemas com a multiplicação por zero. -
Teste com números grandes:
Este teste verifica se a função de multiplicação consegue lidar com números grandes sem sobrecarregar ou ter problemas de precisão. Estamos multiplicando dois valores de um milhão por um milhão, esperando um resultado de um trilhão. Este teste é crucial porque verifica os limites superiores das capacidades da função. Note que isso poderia falhar se a implementação do servidor não lidar corretamente com números grandes, o que poderia indicar a necessidade de bibliotecas de números grandes ou um tipo de dado diferente. -
Teste intencionalmente defeituoso:
Este teste está deliberadamente configurado para falhar. Ele verifica se 2 * 3 é igual a 7, o que é incorreto. Este teste visa demonstrar o aspecto de um teste defeituoso no resultado do teste. Isto ajuda a entender como identificar e debugar testes defeituosos, que é uma habilidade essencial em desenvolvimento de testes dirigidos e processos de depuração.
Ao incluir estes casos de borda e uma falha intencional, você está testando não apenas a funcionalidade básica da sua rota de multiplicação, mas também o seu comportamento sob condições extremas e suas capacidades de relatório de erros. Esta abordagem de teste ajuda a garantir a robustez e a confiabilidade da nossa aplicação.
Vamos tentar executar os testes novamente:
Você deveria ver o seguinte output:
A mensagem de falha acima indica que o teste test_multiply_edge_cases
no arquivo tests/test_app.py
falhou. Especificamente, a última afirmação nesta função de teste causou a falha.
Essa falha intencional é útil para mostrar como são relatadas falhas de teste e quais informações são fornecidas na mensagem de falha. Ela mostra exatamente na linha onde ocorreu a falha, os valores esperados e reais, e a diferença entre eles.
Em um cenário real, você corrigiria o código para tornar o teste passar ou ajustaria o teste se o resultado esperado estivesse incorreto. No entanto, neste caso, a falha é intencional para fins educacionais.
Conclusão
Neste tutorial, abordamos como configurar testes unitários para uma aplicação Flask usando o pytest
, integrar fixtures do pytest
e mostrarão o que uma falha de teste se parece. Ao seguir estas etapas, você pode garantir que suas aplicações Flask são confiáveis e manutenveis, minimizando erros e melhorando a qualidade do código.
Você pode referir-se à documentação oficial de Flask e Pytest para aprender mais.
Source:
https://www.digitalocean.com/community/tutorials/unit-test-in-flask