Curso
Tutorial de teste de unidade em Python
O teste de unidade é um método de teste de software pelo qual unidades individuais de código-fonte são submetidas a vários testes para determinar se estão aptas para uso. Ele determina e verifica a qualidade do seu código.
Geralmente, quando o processo de desenvolvimento é concluído, o desenvolvedor codifica os critérios ou os resultados que são conhecidos como potencialmente práticos e úteis no script de teste para verificar a correção de uma unidade específica. Durante a execução do caso de teste, várias estruturas registram os testes que falham em qualquer critério e os relatam em um resumo.
Espera-se que os desenvolvedores escrevam scripts de teste automatizados, o que garante que cada seção ou unidade atenda ao seu projeto e se comporte conforme o esperado.
Teste de unidade Python
Embora escrever testes manuais para o seu código seja definitivamente uma tarefa tediosa e demorada, a estrutura de teste de unidade integrada do Python tornou a vida muito mais fácil.
A estrutura de teste de unidade em Python é chamada unittest
, que vem com o Python.
O teste de unidade torna seu código à prova de futuro, pois você antecipa os casos em que seu código poderia falhar ou produzir um bug. Embora não seja possível prever todos os casos, você ainda pode lidar com a maioria deles.
Uma unidade pode ser agrupada em várias categorias:
- Um módulo inteiro,
- Uma função individual,
- Uma interface completa, como uma classe ou um método.
A melhor maneira de escrever testes unitários para o seu código é começar com a menor unidade testável que o seu código possa ter, depois passar para outras unidades e ver como essa menor unidade interage com outras unidades, dessa forma você pode criar um teste unitário abrangente para os seus aplicativos.
A estrutura de teste de unidade do Python foi inspirada no JUnit
do Java e tem recursos semelhantes aos das principais estruturas de teste de unidade em outras linguagens. A estrutura de teste de unidade do Python oferece a você vários recursos recursosincluindo:
- Automação de testes
- Compartilhamento do código de configuração e desligamento para testes
- Agregação de testes em coleções
- Independência dos testes em relação à estrutura de relatórios
Agora vamos dar um exemplo e entender por que você precisa fazer testes unitários do seu código.
Como começar a usar o Python unittest
Abaixo, descrevemos as etapas que você precisa para usar a estrutura unittest
do Python
Criando uma função de cubo
Vamos escrever um código para você calcular o volume de um cubo em Python
def cuboid_volume(l):
return (l*l*l)
length = [2,1.1, -2.5, 2j, 'two']
for i in range(len(length)):
print ("The volume of cuboid:",cuboid_volume(length[i]))
The volume of cuboid: 8
The volume of cuboid: 1.3310000000000004
The volume of cuboid: -15.625
The volume of cuboid: (-0-8j)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-67e1c37a435f> in <module>
1 for i in range(len(length)):
----> 2 print ("The volume of cuboid:",cuboid_volume(length[i]))
<ipython-input-2-f50464fd88da> in cuboid_volume(l)
1 def cuboid_volume(l):
----> 2 return (l*l*l)
TypeError: can't multiply sequence by non-int of type 'str'
Análise de resultados
O resultado acima deve dar a você alguma intuição sobre a importância de ter um teste de unidade implementado para o seu código. Agora, há três coisas que certamente estão incorretas no código acima:
- Primeiro, o volume do cuboide é negativo,
- Em segundo lugar, o volume do cuboide é um número complexo,
- Por fim, o código resulta em um
TypeError
, pois você não pode multiplicar uma cadeia de caracteres, que não é um ponto.
Felizmente, o terceiro problema resultou em um erro, enquanto o primeiro e o segundo foram bem-sucedidos, embora o volume do cuboide não possa ser negativo e seja um número complexo.
Os testes de unidade geralmente são escritos como um código separado em um arquivo diferente, e pode haver diferentes convenções de nomenclatura que você pode seguir. Você pode escrever o nome do arquivo de teste de unidade como name of the code/unit + test
separado por um sublinhado ou test + name of the code/unit
separado por um sublinhado.
Por exemplo, digamos que o nome do arquivo de código acima seja cuboid_volume.py
, então o nome do código de teste de unidade poderia ser cuboid_volume_test.py
Sem mais delongas, vamos escrever o teste de unidade para o código acima.
Using assertAlmostEqual
Primeiro, vamos criar um arquivo Python com o nome volume_cuboid.py
, que terá o código para calcular o volume e o segundo com o nome test_volume_cuboid.py
, que terá o código de teste de unidade.
import unittest
A classe TestCuboid
herda o módulo unittest
e, nessa classe, você definirá vários métodos que deseja que o teste de unidade verifique com a função cuboid_volume
.
A primeira função que você definirá é test_volume
, que verificará se o resultado que o cuboid_volume
fornece é igual ao que você espera. Para isso, você usará o método assertAlmostEqual
.
Teste 1
class TestCuboid(unittest.TestCase):
def test_volume(self):
self.assertAlmostEqual(cuboid_volume(2),8)
self.assertAlmostEqual(cuboid_volume(1),1)
self.assertAlmostEqual(cuboid_volume(0),0)
self.assertAlmostEqual(cuboid_volume(5.5),166.375)
Vamos executar o script acima. Você executaria o módulo unittest
como um script, especificando -m
ao executá-lo.
!python -m unittest test_volume_cuboid.py
Saída:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Ótimo! Então você conseguiu que seu primeiro código de teste de unidade funcionasse.
O teste foi executado com sucesso e retornou OK
, o que significa que a função cuboid_volume funciona como você espera.
Teste 2
Vamos ver o que acontece quando um dos métodos do assertAlmostEqual
falha.
Observe que a última instrução assert foi modificada.
!python -m unittest test_volume_cuboid.py
Saída:
F
======================================================================
FAIL: test_volume (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 15, in test_volume
self.assertAlmostEqual(cuboid_volume(5.5),0)
AssertionError: 166.375 != 0 within 7 places (166.375 difference)
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Bem, a partir da saída acima, você pode observar que a última instrução assert resultou em um AssertionError
, portanto, uma falha no teste de unidade. O módulo de teste de unidade do Python mostra a você o motivo da falha, juntamente com o número de falhas do seu código.
Usando assertRaises
Agora vamos explorar outro método de asserção, ou seja, assertRaises
, que ajudará você a descobrir se a função cuboid_volume
trata os valores de entrada corretamente.
Digamos que você queira testar se a sua função cuboid_volume
trata a classe ou o tipo de entrada, por exemplo, se você passar uma string como entrada, ela tratará essa entrada como uma exceção ou com uma condição if, já que o comprimento do cuboide nunca pode ser uma string.
!python -m unittest test_volume_cuboid.py
Saída:
F.
======================================================================
FAIL: test_input_value (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 17, in test_input_value
self.assertRaises(TypeError, cuboid_volume, True)
AssertionError: TypeError not raised by cuboid_volume
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
Ótimo! Portanto, a partir da saída acima, fica evidente que o seu código volume_cuboid.py
não cuida adequadamente da entrada que está sendo passada a ele.
Modificando a função de cubo
Vamos adicionar uma condição no site volume_cuboid.py
para verificar se a entrada ou o comprimento do cuboide é um booleano ou uma cadeia de caracteres e gerar um erro.
!python -m unittest test_volume_cuboid.py
Saída:
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
Executando o script de teste Python no laboratório Jupyter
Vamos agora executar o script de teste no laboratório do jupyter. Para isso, você deve primeiro definir o script de teste no laboratório do jupyter, conforme mostrado abaixo.
# -*- coding: utf-8 -*-
"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""
from volume_cuboid import *
import unittest
class TestCuboid(unittest.TestCase):
def test_volume(self):
self.assertAlmostEqual(cuboid_volume(2),8)
self.assertAlmostEqual(cuboid_volume(1),1)
self.assertAlmostEqual(cuboid_volume(0),1)
def test_input_value(self):
self.assertRaises(TypeError, cuboid_volume, True)
Em seguida, você usará o método unittest.main()
para executar o script de teste. Você pode passar vários argumentos para o método abaixo, dos quais um é verbosity level
.
Vamos experimentar com diferentes níveis de verbosidade e ver como isso altera a descrição da saída.
Verbosidade 0
unittest.main(argv=[''],verbosity=0, exit=False)
Output:
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
<unittest.main.TestProgram at 0x1de02774348>
Verbosidade 1
unittest.main(argv=[''],verbosity=1, exit=False)
Output:
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgram at 0x1de027a1cc8>
Verbosidade 2
unittest.main(argv=[''],verbosity=2, exit=False)
Output:
test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgram at 0x1de027a8308>
Visualizando o AssertionError
Por fim, vamos modificar o final assertAlmostEqual
no método test_volume
e analisar como o nível de verbosidade 2 mostrará a falha do método.
# -*- coding: utf-8 -*-
"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""
from volume_cuboid import *
import unittest
class TestCuboid(unittest.TestCase):
def test_volume(self):
self.assertAlmostEqual(cuboid_volume(2),8)
self.assertAlmostEqual(cuboid_volume(1),1)
self.assertAlmostEqual(cuboid_volume(0),1)
def test_input_value(self):
self.assertRaises(TypeError, cuboid_volume, True)
unittest.main(argv=[''],verbosity=2, exit=False)
Saída:
test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... FAIL
======================================================================
FAIL: test_volume (__main__.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<ipython-input-28-46ad33b909ee>", line 14, in test_volume
self.assertAlmostEqual(cuboid_volume(0),1)
AssertionError: 0 != 1 within 7 places (1 difference)
----------------------------------------------------------------------
Ran 2 tests in 0.003s
FAILED (failures=1)
<unittest.main.TestProgram at 0x1de027b5448>
Resumo
Com base nos resultados acima, você pode tirar as seguintes conclusões:
- O nível de verbosidade 0 mostra apenas quantos testes foram executados, ou seja, 2 testes e o tempo que você levou para executá-los,
- Nível de verbosidade 1: adicionar dois pontos .. o que significa que dois testes foram executados,
- O nível de verbosidade 2 mostra os nomes detalhados dos métodos que foram executados juntamente com seu estado
OK
ouFAIL
.
Métodos de afirmação do unittest disponíveis
Há muitos métodos de asserção no módulo de teste de unidade do Python, que podem ser aproveitados para fins de teste.
Métodos de afirmação comumente usados
Fonte: documentação do unittest
Verificações de produção
Usando os métodos a seguir, você pode verificar a produção de exceções, avisos e mensagens de log.
Fonte: documentação do unittest
Métodos específicos de tarefas
Fonte: documentação do unittest
Para saber em detalhes sobre os métodos de assert
, você pode consultar a documentação oficial do Python documentação oficial do Python.
Você também pode aprender sobre eles com a ajuda do módulo Pydoc
, que é semelhante a uma função help
em Python. Uma demonstração de como você poderia usar o módulo Pydoc para ler sobre a documentação do método assertCountEqual
é mostrada abaixo.
!python -m pydoc unittest.TestCase.assertCountEqual
Saída:
Help on function assertCountEqual in unittest.TestCase:
unittest.TestCase.assertCountEqual = assertCountEqual(self, first, second, msg=None)
An unordered sequence comparison asserting that the same elements,
regardless of order. If the same element occurs more than once,
it verifies that the elements occur the same number of times.
self.assertEqual(Counter(list(first)),
Counter(list(second)))
Example:
- [0, 1, 1] and [1, 0, 1] compare equal.
- [0, 0, 1] and [0, 1] compare unequal.
Conclusão
Este tutorial foi uma introdução básica aos testes unitários em Python e sua importância como desenvolvedor. Um bom exercício para você seria escrever um módulo de teste de unidade para qualquer um de seus projetos anteriores. Isso dará a você uma boa experiência prática com a criação de testes de unidade. Além disso, tente explorar os métodos Assert restantes. Você pode ler mais sobre testes unitários em nosso tutorial do Pytest.
Se você está começando a usar Python e gostaria de saber mais, assista ao nosso curso Introdução à ciência de dados em Python para você.
Torne-se um desenvolvedor Python

Sou um cientista de dados certificado que gosta de criar aplicativos de aprendizado de máquina e escrever blogs sobre ciência de dados. No momento, estou me concentrando na criação e edição de conteúdo e no trabalho com modelos de linguagem de grande porte.
Aprenda mais sobre Python com estes cursos!
Curso
Intermediate Python for Developers
Curso
Python Toolbox

Tutorial
Como usar o Pytest para testes de unidade
Tutorial
Tutorial de como executar scripts Python
Tutorial
Tutorial de docstrings em Python
Tutorial
Tutorial de funções Python
Tutorial
Tutorial de conjuntos e teoria de conjuntos em Python

DataCamp Team
13 min
Tutorial