Trilha de aprendizado · Nível 8 · Tutorial 1

Escrever e executar testes de funções com pytest

Criar testes automatizados para funções, executá-los com pytest no ambiente do projeto e interpretar os resultados das verificações.

  • Nível: Intermediário
  • Duração: 16 min
  • 8 passos
Escrever e executar testes de funções com pytest

O que você vai percorrer

  1. Transformar uma expectativa em teste Diferencie a simples observação de uma saída de uma verificação executável que sinaliza quando o comportamento obtido diverge do esperado. 1 min
  2. Organizar o projeto para a descoberta dos testes Prepare o ambiente, os arquivos e os nomes que permitem ao pytest localizar os testes e importar a função testada. 2 min
  3. Escrever verificações com assert Construa funções de teste com preparação dos dados, chamada da função e comparação entre o resultado obtido e o esperado. 3 min
  4. Executar os testes no ambiente do projeto Execute toda a suíte local com pytest e reconheça os sinais de que os testes foram encontrados e aprovados. 2 min
  5. Executar apenas o teste necessário Compare os comandos para executar toda a suíte, um arquivo de testes ou uma única função de teste. 2 min
  6. Interpretar uma verificação que falhou Ler o relatório de uma falha de assert, identificar os valores que divergiram e restaurar a expectativa correta. 2 min
  7. Distinguir falha de verificação e erro de execução Use a fase, o tipo da exceção e a localização do problema para interpretar relatórios do pytest. 2 min
  8. Aplicar o fluxo completo de teste Consolide o fluxo de organizar, escrever, executar e interpretar testes de funções com pytest. 3 min

O que você vai aprender

  • Organizar arquivos e funções de teste conforme as convenções de descoberta do pytest.
  • Escrever verificações com assert a partir de entradas e resultados esperados.
  • Executar todos os testes ou selecionar um teste específico.
  • Distinguir uma verificação que falhou de um erro que impediu a coleta ou a execução do teste.

Antes de começar

  • Definir funções com parâmetros e retorno
  • Separar código em módulos e usar importações explícitas
  • Controlar a execução de módulos com __name__
  • Instalar pacotes com pip no ambiente correto

Passo 1 de 8

Transformar uma expectativa em teste

Diferencie a simples observação de uma saída de uma verificação executável que sinaliza quando o comportamento obtido diverge do esperado.

Observar não é verificar

Do resultado à verificação

Usar print permite olhar o retorno de uma função, mas deixa a decisão por sua conta. Um teste automatizado vai além: ele compara o resultado obtido com um resultado esperado e sinaliza quando há divergência.

Exemplo

Duas abordagens

Imagine a entrada " Olá Mundo ". Apenas exibir "olá mundo" permite uma conferência visual. Uma verificação automatizada registra a expectativa de que essa entrada produza exatamente "olá mundo" e acusa qualquer resultado diferente.

O caminho de uma expectativa

Entrada, resultado e expectativa

Toda verificação começa com uma entrada conhecida. A função processa essa entrada e devolve o resultado obtido. Esse valor é comparado ao resultado esperado, definido conforme o comportamento desejado.

Fluxo de uma verificação

O diagrama conecta a entrada à chamada da função e mostra a comparação final entre o resultado obtido e o esperado.

Diagrama em que uma entrada passa por uma função, gera um resultado e é comparada a um valor esperado, com caminhos visuais de correspondência e divergência.

Entrada → chamada da função → resultado obtido → comparação com o resultado esperado.

Exemplo

Comportamento usado no tutorial

A função normalizar_texto deve remover espaços apenas das extremidades e converter as letras para minúsculas. Exemplos esperados:

  • " Olá Mundo " → "olá mundo"
  • "PYTHON" → "python"

O papel do pytest

Um executor de testes

O pytest ajuda a descobrir as verificações organizadas como testes, executá-las e apresentar os resultados. Assim, você não precisa conferir manualmente cada saída. Nos próximos steps, você organizará os arquivos, escreverá as verificações e executará o pytest no seu projeto.

Reconheça uma verificação automatizada

Observação ou verificação?

Qual descrição representa uma verificação automatizada do comportamento de normalizar_texto?

Passo 2 de 8

Organizar o projeto para a descoberta dos testes

Prepare o ambiente, os arquivos e os nomes que permitem ao pytest localizar os testes e importar a função testada.

Prepare o ambiente local

Editor, terminal e mesmo interpretador

No seu computador, abra no editor a pasta do projeto e ative o ambiente virtual que você já sabe criar. No terminal desse ambiente, instale o pytest e confirme a instalação. Os dois comandos usam python -m, ajudando a executar o pip e o pytest associados ao mesmo interpretador Python.

Instalação e confirmação

Execute os comandos no terminal do ambiente virtual ativado:

shell
python -m pip install pytest
python -m pytest --version

Dica

Confira antes de continuar

A confirmação deve exibir a versão instalada do pytest. Se o comando não funcionar, verifique se o ambiente virtual correto está ativado e se o terminal usa o Python esperado.

Monte a estrutura do projeto

Onde fica cada arquivo

Na pasta principal do projeto, crie textos.py para o código da aplicação. Dentro da pasta tests, crie test_textos.py para os testes. Execute os comandos do pytest a partir da pasta que contém tanto textos.py quanto tests.

O pytest adota convenções de descoberta: arquivos de teste podem seguir o padrão test_*.py, e as funções de teste começam com test_. O nome tests é uma organização comum, mas não é obrigatório para a descoberta.

Estrutura mínima do projeto

Diagrama em árvore mostrando a pasta do projeto com textos.py e a pasta tests, que contém test_textos.py.

textos.py contém a função da aplicação; tests/test_textos.py reúne os testes que o pytest poderá descobrir.

Separe a função e sua importação

Módulo da aplicação

Escreva a função em textos.py. Ela apenas recebe um texto, remove os espaços das extremidades e converte as letras para minúsculas. Não coloque leitura com input() nem outra interação que seja iniciada durante a importação.

Arquivo textos.py

Conteúdo completo do módulo da aplicação:

python
def normalizar_texto(texto):
    return texto.strip().lower()

Início do arquivo tests/test_textos.py

Por enquanto, registre somente a importação explícita. As funções de teste e suas verificações serão acrescentadas no próximo passo.

python
from textos import normalizar_texto

Dica

Importar sem iniciar interações

Se um módulo também tiver código interativo, mantenha esse código sob a proteção if __name__ == "__main__":, como você já aprendeu. Assim, importar normalizar_texto não inicia perguntas nem outras ações do programa.

Associe nomes e responsabilidades

Mapa do projeto

Relacione cada elemento à sua responsabilidade ou convenção.

Toque em um item e depois no par correspondente.

Passo 3 de 8

Escrever verificações com assert

Construa funções de teste com preparação dos dados, chamada da função e comparação entre o resultado obtido e o esperado.

As três partes de um teste

Preparar, agir e verificar

Uma função de teste pode ser organizada em três blocos:

  1. Preparação: define a entrada e o resultado esperado.
  2. Ação: chama a função da aplicação e guarda o resultado obtido.
  3. Verificação: usa assert para comparar o resultado obtido com o esperado.

Essa separação deixa explícito qual comportamento está sendo verificado.

Fluxo com três blocos: dados de entrada e expectativa, chamada da função e comparação dos resultados.

O teste prepara os valores, executa a função e verifica se o retorno corresponde à expectativa.

O arquivo de testes completo

Duas funções descobertas pelo pytest

No arquivo tests/test_textos.py, importe a função da aplicação e crie funções sem parâmetros cujos nomes começam com test_. Cada teste abaixo verifica um exemplo de sucesso já definido para normalizar_texto.

tests/test_textos.py

Crie ou substitua o conteúdo do arquivo pelo código completo:

python
from textos import normalizar_texto


def test_normalizar_texto():
    # Preparação
    entrada = "  Olá, Mundo!  "
    esperado = "olá, mundo!"

    # Ação
    resultado = normalizar_texto(entrada)

    # Verificação
    assert resultado == esperado


def test_normalizar_texto_em_minusculas():
    # Preparação
    entrada = "PYTHON"
    esperado = "python"

    # Ação
    resultado = normalizar_texto(entrada)

    # Verificação
    assert resultado == esperado

Dica

Nenhuma importação adicional

Esses testes não precisam de import pytest: a instrução assert já faz parte da linguagem Python. O pytest encontra as funções test_*, executa cada uma e apresenta o resultado.

O que o assert verifica

Uma condição que precisa ser verdadeira

Em assert resultado == esperado, a expressão de igualdade produz uma condição:

  • Se for verdadeira, a execução do teste continua normalmente.
  • Se for falsa, Python levanta AssertionError e interrompe aquele teste.

O assert registra uma expectativa do teste. Ele não modifica o resultado para fazê-lo coincidir com o valor esperado.

Atenção

Assert não substitui validações da aplicação

Use assert para verificar comportamentos nos testes. Não o use como substituto das validações de entrada que pertencem à função da aplicação, pois essas validações devem funcionar independentemente da execução dos testes.

Complete a verificação

Bloco de verificação

Complete apenas o lado direito do assert:

entrada = "PYTHON"
esperado = "python"
resultado = normalizar_texto(entrada)

assert resultado == ____

Passo 4 de 8

Executar os testes no ambiente do projeto

Execute toda a suíte local com pytest e reconheça os sinais de que os testes foram encontrados e aprovados.

Executar toda a suíte

Comece pela pasta do projeto

Abra o terminal na pasta que contém textos.py e a pasta tests. Com o ambiente virtual do projeto ativo, execute toda a suíte com o comando abaixo. A forma python -m pytest usa o pytest associado ao mesmo interpretador indicado por python.

Comando de execução

Execute no terminal, a partir da pasta do projeto:

shell
python -m pytest

Dica

Confira o ponto de partida

Antes de executar, verifique se a pasta atual contém textos.py e tests. O pytest procura os testes a partir do local em que o comando foi iniciado.

Da descoberta ao resultado

O que acontece durante o comando

O pytest primeiro descobre e coleta as funções de teste reconhecidas. Depois, executa cada uma e apresenta um resumo. Com os dois testes criados anteriormente, uma execução bem-sucedida deve indicar dois itens coletados, dois pontos de aprovação e o total 2 passed.

Fluxo da execução

Diagrama em que uma pasta de projeto leva à descoberta dos testes, depois à execução de dois testes e, por fim, a um relatório com duas aprovações.

Fluxo básico: localizar arquivos e funções de teste, coletá-los, executá-los e apresentar o resultado.

Exemplo de saída aprovada

Partes menos importantes da saída podem variar conforme o sistema e a versão instalada.

text
============================= test session starts =============================
collected 2 items

tests/test_textos.py ..                                               [100%]

============================== 2 passed in 0.03s ==============================

Nenhum teste não significa aprovação

Atenção

Atenção a “no tests ran”

Se o relatório mostrar collected 0 items ou no tests ran, nenhum teste foi executado. Isso não equivale a uma suíte aprovada.

Exemplo sem testes coletados

Esta saída não contém verificações aprovadas:

text
============================= test session starts =============================
collected 0 items

============================ no tests ran in 0.01s =============================

Primeiras conferências

Nesse caso, confirme se o terminal está na pasta que contém o projeto e se os nomes seguem as convenções adotadas: arquivo test_*.py e funções test_*. Em seguida, execute novamente python -m pytest.

Registre sua execução

Execute no seu computador

Na pasta que contém textos.py e tests, execute toda a suíte. Registre o comando usado, quantos testes foram coletados e o resultado final observado. Se nenhum teste for coletado, faça as conferências iniciais e tente novamente.

Escreva pelo menos 30 caracteres (0/30).

Passo 5 de 8

Executar apenas o teste necessário

Compare os comandos para executar toda a suíte, um arquivo de testes ou uma única função de teste.

Três escopos de execução

Você pode ajustar o escopo da execução conforme sua intenção: verificar toda a suíte, somente um arquivo ou uma única função. Execute o comando escolhido no terminal, a partir da pasta do projeto.

Comandos por escopo

Use somente o comando correspondente ao escopo desejado.

bash
# Toda a suíte
python -m pytest

# Somente o arquivo indicado
python -m pytest tests/test_textos.py

# Somente uma função do arquivo
python -m pytest tests/test_textos.py::test_normalizar_texto

Do projeto até uma única função

Comparação visual entre os escopos de toda a suíte, de um arquivo e de uma única função de teste.

Cada comando reduz o escopo: suíte completa → arquivo test_textos.py → função test_normalizar_texto.

Montar o identificador do teste

Caminho, separador e nome exato

Para selecionar uma função, escreva o caminho do arquivo, acrescente o separador :: e informe o nome exato da função. Não inclua parênteses. Neste projeto, o identificador é tests/test_textos.py::test_normalizar_texto.

Execute uma única função

Copie o comando no terminal do projeto.

bash
python -m pytest tests/test_textos.py::test_normalizar_texto

Dica

Confirme o escopo na saída

Ao executar esse comando, confira se o relatório identifica test_normalizar_texto e informa apenas 1 teste aprovado. Se mais testes forem executados, revise o caminho, o separador :: e o nome usado.

Escolha o comando adequado

Relacione intenção e comando

Associe cada intenção de execução ao comando correspondente.

Toque em um item e depois no par correspondente.

Passo 6 de 8

Interpretar uma verificação que falhou

Ler o relatório de uma falha de assert, identificar os valores que divergiram e restaurar a expectativa correta.

Produza uma falha controlada

Uma expectativa propositalmente incorreta

A regra de normalizar_texto continua sendo: remover espaços das extremidades e converter as letras para minúsculas. Para observar o relatório de falha, altere temporariamente a expectativa do teste para "Python". Essa expectativa está explicitamente incorreta.

Trecho temporário de tests/test_textos.py

Use este conteúdo apenas para provocar e analisar a falha:

python
from textos import normalizar_texto


def test_normalizar_texto():
    entrada = "  Python  "
    resultado = normalizar_texto(entrada)
    esperado = "Python"  # incorreto de propósito

    assert resultado == esperado

Execute somente esse teste

No terminal, a partir da pasta que contém textos.py e tests, execute:

shell
python -m pytest tests/test_textos.py::test_normalizar_texto

Leia o relatório da falha

Exemplo de saída

A apresentação exata pode variar conforme a versão do pytest, mas os indicadores principais são estes:

text
tests/test_textos.py F                                      [100%]

=================== FAILURES ===================
____________ test_normalizar_texto ____________

    assert resultado == esperado
E   AssertionError: assert 'python' == 'Python'

FAILED tests/test_textos.py::test_normalizar_texto
================== 1 failed ===================

Anatomia da falha

O relatório conecta o teste afetado à linha do assert e à comparação que resultou em falso.

Diagrama de um relatório do pytest destacando o indicador F, o teste que falhou, a linha do assert e os valores obtido e esperado.

No assert resultado == esperado, o operando da esquerda contém o valor obtido; o da direita contém o valor esperado.

O que os indicadores revelam

F marca o teste que terminou com falha, e FAILED identifica esse teste no resumo. A linha com AssertionError mostra que a condição do assert foi falsa: o resultado obtido foi "python", enquanto o teste exigia "Python".

A falha comprova uma divergência, mas não determina sozinha sua causa. A implementação pode estar errada, ou a expectativa do teste pode estar errada. Aqui, a regra fornecida confirma que a expectativa é o problema.

Interprete antes de corrigir

Diagnóstico do relatório

Com base no relatório e na regra de normalizar_texto, explique qual teste falhou, qual comparação foi executada, quais valores divergiram e por que a expectativa estava incorreta.

Escreva pelo menos 80 caracteres (0/80).

Restaure a expectativa correta

Teste corrigido

Restaure a expectativa de acordo com a regra fornecida:

python
from textos import normalizar_texto


def test_normalizar_texto():
    entrada = "  Python  "
    resultado = normalizar_texto(entrada)
    esperado = "python"

    assert resultado == esperado

Confirme a correção

Execute novamente o teste específico. O resumo esperado agora contém 1 passed.

shell
python -m pytest tests/test_textos.py::test_normalizar_texto

Atenção

Não corrija apenas para obter aprovação

Nunca altere o valor esperado apenas para fazer o teste passar. Primeiro confronte a divergência com a regra definida. Depois, corrija a expectativa ou a implementação conforme essa regra.

Passo 7 de 8

Distinguir falha de verificação e erro de execução

Use a fase, o tipo da exceção e a localização do problema para interpretar relatórios do pytest.

Em que fase o problema ocorreu?

Não dependa apenas de FAILED ou ERROR

Leia o relatório combinando três pistas:

  1. Fase: ocorreu durante a coleta, a chamada testada ou a avaliação do assert?
  2. Exceção: foi ModuleNotFoundError, NameError, AssertionError ou outra?
  3. Localização: qual arquivo e linha o rastreamento indica?

Um erro de importação durante a coleta impede que os testes afetados sejam executados. Já uma exceção inesperada dentro de um teste pode aparecer como FAILED, mesmo que nenhum assert tenha sido avaliado.

O caminho até a verificação

Fluxo em três etapas: coleta dos testes, execução da chamada testada e avaliação do assert, com possíveis interrupções em cada etapa.

Da esquerda para a direita: o pytest coleta o teste, executa seu corpo e chega ao assert. Uma importação pode interromper a coleta; uma exceção na chamada pode impedir a chegada ao assert; só no último estágio uma condição falsa produz a falha de verificação.

Três relatórios, três diagnósticos

Leia a exceção antes de concluir

ERROR collecting aponta para um problema ocorrido antes da execução dos testes afetados. Em contraste, o resumo pode usar FAILED tanto para um assert falso quanto para uma exceção inesperada durante a execução. O tipo da exceção e a última linha relevante do rastreamento esclarecem a diferença.

Exemplo

1. Importação interrompida na coleta

ERROR collecting tests/test_textos.py
ModuleNotFoundError: No module named 'textos'

O teste não chegou a ser executado. As primeiras conferências são: pasta atual do terminal, ambiente usado pelo comando, nome do módulo e instrução de importação.

Exemplo

2. Exceção antes do assert

FAILED tests/test_textos.py::test_normalizar_texto
NameError: name 'texto' is not defined
textos.py:2

O teste foi iniciado, mas a chamada encontrou um nome inexistente e não chegou à verificação seguinte. A primeira conferência deve ser a linha indicada e o nome usado nela.

Exemplo

3. Comparação falsa

FAILED tests/test_textos.py::test_normalizar_texto
AssertionError: assert 'python' == 'PYTHON'

Aqui o assert foi avaliado e sua condição era falsa. Compare obtido e esperado com a regra definida, sem alterar a expectativa apenas para fazer o teste passar.

Associe o relatório à primeira conferência

Diagnóstico inicial

Associe cada trecho de relatório à interpretação e à primeira conferência mais adequada.

Toque em um item e depois no par correspondente.

Passo 8 de 8

Aplicar o fluxo completo de teste

Consolide o fluxo de organizar, escrever, executar e interpretar testes de funções com pytest.

O fluxo completo em um projeto

Desafio final

Use o mesmo projeto dos steps anteriores. O arquivo textos.py deve conter a implementação abaixo, e tests/test_textos.py deve manter os dois testes já criados.

Agora você acrescentará um terceiro teste para esta expectativa: ao receber " PyTest PRÁTICO \n", a função deve retornar "pytest prático".

Implementação completa — textos.py

Confirme que o módulo contém esta função, sem código interativo executado durante a importação.

python
def normalizar_texto(texto):
    return texto.strip().lower()

Do projeto ao diagnóstico

O trabalho com testes forma um ciclo: organizar os arquivos, escrever uma verificação, executá-la e interpretar o relatório.

Diagrama em quatro etapas conectadas: estrutura de arquivos, função de teste, execução no terminal e inspeção do resultado.

O relatório conduz de volta ao código quando uma verificação não produz o resultado esperado.

Escreva e execute o novo teste

Prática no seu computador

No final de tests/test_textos.py, acrescente a função abaixo. Ela separa preparação, ação e verificação. Depois, execute primeiro somente esse teste e, em seguida, toda a suíte a partir da pasta que contém textos.py e tests.

Novo teste e comandos

O arquivo já deve conter from textos import normalizar_texto. Acrescente a função e execute os dois comandos no terminal.

python
def test_normalizar_texto_com_quebra_de_linha():
    entrada = "  PyTest PRÁTICO \n"

    resultado = normalizar_texto(entrada)

    assert resultado == "pytest prático"


# Execute no terminal, sem copiar estas duas linhas para o arquivo Python:
# python -m pytest tests/test_textos.py::test_normalizar_texto_com_quebra_de_linha
# python -m pytest

Registre o que aconteceu

Registre: o nome e o assert do teste, os dois comandos executados e o resultado principal de cada execução. Compare sua resposta com a referência exibida depois do envio.

Escreva pelo menos 80 caracteres (0/80).

Revise os diagnósticos

Associe cada relatório à interpretação

Relacione cada sinal do pytest ao diagnóstico mais adequado.

Toque em um item e depois no par correspondente.

Síntese e conclusão

Resumo

Fluxo que você consolidou

Você completou o primeiro ciclo de testes automatizados com pytest.

  • Organizar o módulo e o arquivo de teste conforme as convenções de descoberta.
  • Escrever uma função test_* com preparação, ação e verificação por assert.
  • Executar um teste pelo identificador e depois executar toda a suíte.
  • Interpretar o relatório pela fase, pela exceção e pela localização do problema.
  • Lembrar que testes aprovados confirmam apenas as verificações executadas; eles não garantem a ausência de outros defeitos.

Tutorial concluído

Parabéns! Você concluiu: Escrever e executar testes de funções com pytest

Parabéns! Você concluiu “Escrever e executar testes de funções com pytest” e está pronto para aprender a selecionar novos casos de teste e verificar exceções.

100 XP

Baixe o Aplicativo agora para ter acesso a + de 5000 cursos gratuitos, exercícios, certificado e muito conteúdo sem pagar nada!

  • Cursos online 100% gratuitos do início ao fim

    Milhares de cursos online em vídeo, ebooks e áudiobooks.

  • Mais de 60 mil exercícios gratuitos

    Para testar seus conhecimentos no decorrer dos cursos online

  • Certificado Digital gratuito válido em todo o Brasil

    Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail

Aplicativo Cursa na tela de ebook, na tela de curso em vídeo e na tela de exercícios do curso, mais o certificado de conclusão de curso