Exercício
Neste exercício, você usará pytest com parametrizar para testar uma função. Em seguida, você atualiza uma classe de teste para usar uma instalação em vez de um método setup() e teardown(). Usar parametrizar e trabalhar com acessórios permite que você se torne mais flexível ao criar ou atualizar testes.
Etapa 1 – Adicionar um arquivo com testes para este exercício
Crie um arquivo de teste chamado test_advanced.py e adicione o seguinte código:
def str_to_bool(string): if string.lower() in ['yes', 'y', '1']: return True elif string.lower() in ['no', 'n', '0']: return FalseA função
str_to_bool()aceita uma cadeia de caracteres como entrada e, dependendo de seu conteúdo, retorna um valorTrueouFalse.No mesmo arquivo, anexe os testes para a função
str_to_bool(). Usepytest.mark.parametrize()para testar todos os valores verdadeiros primeiro:import pytest @pytest.mark.parametrize("string", ['Y', 'y', '1', 'YES']) def test_str_to_bool_true(string): assert str_to_bool(string) is TrueEm seguida, acrescente outro teste com os valores falsos:
@pytest.mark.parametrize("string", ['N', 'n', '0', 'NO']) def test_str_to_bool_false(string): assert str_to_bool(string) is FalseAgora há dois testes que abrangem todas as entradas possíveis para os valores retornados
TrueeFalse.
Observação
Não é comum colocar os testes no mesmo arquivo que o código real. Para simplificar, os exemplos neste exercício terão o código real no mesmo arquivo. Em projetos de Python do mundo real, você verá que os testes são separados por arquivos e diretórios do código que estão testando.
Etapa 2 – Executar os testes e explorar o relatório
Depois de adicionar os testes, a próxima etapa é executar pytest e inspecionar a saída. Use o sinalizador de detalhamento maior (-v) para ver todos os valores de entrada tratados como um teste separado.
$ pytest -v test_avanced.py
============================= test session starts ==============================
Python 3.9.6, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /private
collected 8 items
test_advanced.py::test_str_to_bool_true[Y] PASSED [ 12%]
test_advanced.py::test_str_to_bool_true[y] PASSED [ 25%]
test_advanced.py::test_str_to_bool_true[1] PASSED [ 37%]
test_advanced.py::test_str_to_bool_true[YES] PASSED [ 50%]
test_advanced.py::test_str_to_bool_false[N] PASSED [ 62%]
test_advanced.py::test_str_to_bool_false[n] PASSED [ 75%]
test_advanced.py::test_str_to_bool_false[0] PASSED [ 87%]
test_advanced.py::test_str_to_bool_false[NO] PASSED [100%]
============================== 8 passed in 0.01s ===============================
Embora você tenha escrito apenas duas funções de teste, pytest foi capaz de criar oito testes no total graças à função parametrize().
Etapa 3 – Mover um teste existente para um acessório
Adicione um novo teste baseado em classe ao arquivo test_advanced.py. Esse teste deve usar uma função
setup()eteardown()que cria um arquivo temporário com algum texto. Após cada teste, o arquivo é removido. Ele deverá ser parecido com:import os class TestFile: def setup(self): with open("/tmp/done", 'w') as _f: _f.write("1") def teardown(self): try: os.remove("/tmp/done") except OSError: pass def test_done_file(self): with open("/tmp/done") as _f: contents = _f.read() assert contents == "1"Essa classe de teste cria um arquivo, mas é problemática porque o caminho /tmp/ não tem garantia de estar presente em todos os sistemas.
Crie um acessório que use o acessório
pytesttmpdir()para gravar no arquivo e retornar o caminho:import pytest @pytest.fixture def tmpfile(tmpdir): def write(): file = tmpdir.join("done") file.write("1") return file.strpath return writeA instalação
tmpfile()usa a instalação detmpdir()do pytest, que garante um arquivo temporário válido que é limpo após a conclusão dos testes.Atualize a classe
TestFilepara que ela use o acessório em vez dos métodos auxiliares:class TestFile: def test_f(self, tmpfile): path = tmpfile() with open(path) as _f: contents = _f.read() assert contents == "1"Essa classe de teste agora pode garantir que um arquivo temporário seja criado e tenha o conteúdo adequado para que a declaração funcione.
Verificar seu trabalho
Agora, você deve ter um arquivo Python chamado test_advanced.py com o seguinte código:
- Uma função
str_to_bool()que aceita uma cadeia de caracteres e retorna um valor booliano dependendo do conteúdo da cadeia de caracteres. - Dois testes parametrizados para a função
str_to_bool(), um que testa os valoresTruee o outro que testa os valoresFalse. - Um dispositivo de
pytestpersonalizado que usa a instalação detmpdir()para criar um temporário feito arquivo com algum conteúdo. - Uma classe de teste que usa o acessório
tmpfile()personalizado para criar o arquivo.
Todos os testes devem ser aprovados ao executá-los no terminal, sem erros.