Python possui um módulo de teste de unidade embutido chamado unittest
, inspirado na estrutura JUnit do Java. Ele fornece uma base para criar casos de teste, suítes de teste e relatórios.
Componentes Principais do unittest
:
TestCase
: Uma classe que herda de unittest.TestCase
. Cada método dentro desta classe que começa com test_
é um teste unitário.TestCase
para verificar condições. Se uma asserção falhar, o teste falha.
assertEqual(a, b)
: Verifica se a == b
.assertTrue(x)
: Verifica se x
é True.assertFalse(x)
: Verifica se x
é False.assertIn(membro, container)
: Verifica se membro
está em container
.assertRaises(Excecao, funcao, *args, **kwargs)
: Verifica se uma Excecao
é levantada quando a funcao
é chamada.setUp()
e tearDown()
(Opcionais):
setUp()
: Executado antes de cada método de teste (test_...
). Usado para configurar o ambiente (criar objetos, abrir arquivos temporários).tearDown()
: Executado após cada método de teste. Usado para limpar o ambiente (excluir arquivos temporários, fechar conexões).unittest
:Vamos criar um módulo de funções simples (matematica.py
) e depois um arquivo de teste para ele (test_matematica.py
).
matematica.py
:
# matematica.py
def somar(a, b):
"""Retorna a soma de dois números."""
return a + b
def subtrair(a, b):
"""Retorna a diferença entre dois números."""
return a - b
def multiplicar(a, b):
"""Retorna o produto de dois números."""
return a * b
def dividir(a, b):
"""Retorna a divisão de dois números. Lida com divisão por zero."""
if b == 0:
raise ValueError("Não é possível dividir por zero.")
return a / b
test_matematica.py
:
# test_matematica.py
import unittest
from matematica import somar, subtrair, multiplicar, dividir
class TestMatematica(unittest.TestCase): # Sua classe de teste deve herdar de unittest.TestCase
def setUp(self):
# Este método é executado antes de CADA teste (test_...)
print("\\nConfigurando para o teste...")
self.valor_inicial = 10 # Exemplo de configuração
self.outro_valor = 5
def tearDown(self):
# Este método é executado após CADA teste (test_...)
print("Limpando após o teste...")
# Normalmente aqui você fecharia arquivos, resetaria banco de dados, etc.
self.valor_inicial = None
self.outro_valor = None
def test_somar(self):
"""Testa a função somar."""
print("Executando test_somar...")
self.assertEqual(somar(2, 3), 5)
self.assertEqual(somar(-1, 1), 0)
self.assertEqual(somar(self.valor_inicial, self.outro_valor), 15)
def test_subtrair(self):
"""Testa a função subtrair."""
print("Executando test_subtrair...")
self.assertEqual(subtrair(5, 2), 3)
self.assertEqual(subtrair(self.valor_inicial, self.outro_valor), 5)
def test_multiplicar(self):
"""Testa a função multiplicar."""
print("Executando test_multiplicar...")
self.assertEqual(multiplicar(2, 4), 8)
self.assertEqual(multiplicar(self.valor_inicial, self.outro_valor), 50)
def test_dividir_numeros_validos(self):
"""Testa a função dividir com números válidos."""
print("Executando test_dividir_numeros_validos...")
self.assertEqual(dividir(10, 2), 5)
self.assertAlmostEqual(dividir(10, 3), 3.333333, places=6) # Para floats, use assertAlmostEqual
def test_dividir_por_zero_levanta_erro(self):
"""Verifica se dividir por zero levanta um ValueError."""
print("Executando test_dividir_por_zero_levanta_erro...")
with self.assertRaises(ValueError): # Verifica se o erro esperado é levantado
dividir(10, 0)
# Para rodar os testes a partir do próprio arquivo
if __name__ == '__main__':
unittest.main()
Como Rodar os Testes:
matematica.py
e test_matematica.py
) na mesma pasta.python -m unittest test_matematica.py
Ou simplesmente: python test_matematica.py
(porque usamos if __name__ == '__main__': unittest.main()
)Saída Esperada (simplificada, pois os prints de setup/teardown aparecem):
Configurando para o teste...
Executando test_somar...
Limpando após o teste...
.
Configurando para o teste...
Executando test_subtrair...
Limpando após o teste...
.
Configurando para o teste...
Executando test_multiplicar...
Limpando após o teste...
.
Configurando para o teste...
Executando test_dividir_numeros_validos...
Limpando após o teste...
.
Configurando para o teste...
Executando test_dividir_por_zero_levanta_erro...
Limpando após o teste...
.
----------------------------------------------------------------------
Ran 5 tests in X.XXXs
OK
Os pontos (.
) indicam que cada teste passou. Se houvesse uma falha ou erro, veríamos F
ou E
.