<h2>Fundamentos de Testes Automatizados</h2>
<p>Os testes automatizados são a espinha dorsal do desenvolvimento moderno. Enquanto testes manuais consomem tempo e são propensos a erros humanos, os testes automatizados executam verificações repetitivas com precisão, permitindo que você implante código com confiança. A pirâmide de testes apresenta três níveis: testes unitários (base), testes de integração (meio) e testes end-to-end (topo). Comece pelos unitários — são rápidos, isolados e testam uma única unidade de código.</p>
<p>Vamos implementar um teste unitário básico em Python usando <code>pytest</code>. Considere uma função que calcula o preço final com desconto:</p>
<pre><code class="language-python">def aplicar_desconto(preco, percentual_desconto):
if percentual_desconto < 0 or percentual_desconto > 100:
raise ValueError("Desconto deve estar entre 0 e 100")
return preco * (1 - percentual_desconto / 100)
Teste unitário
def test_aplicar_desconto_valido():
assert aplicar_desconto(100, 10) == 90.0
assert aplicar_desconto(50, 50) == 25.0
def test_aplicar_desconto_invalido():
with pytest.raises(ValueError):
aplicar_desconto(100, 150)</code></pre>
<p>Execute com <code>pytest nome_arquivo.py</code>. Cada teste é isolado, testando um comportamento específico. Isso garante que refatorações futuras não quebrem funcionalidades esperadas.</p>
<h2>Testes de Integração e Mocks</h2>
<p>Testes de integração verificam como múltiplos componentes trabalham juntos. Aqui entra em jogo o uso de <strong>mocks</strong> — objetos simulados que substituem dependências externas como APIs, bancos de dados ou serviços. Isso permite testar lógica sem depender de sistemas externos.</p>
<p>Considere uma aplicação que busca dados de um usuário em uma API:</p>
<pre><code class="language-python">from unittest.mock import patch, MagicMock
import requests
def buscar_usuario(user_id):
response = requests.get(f"https://api.example.com/users/{user_id}")
if response.status_code == 200:
return response.json()
raise Exception("Usuário não encontrado")
@patch('requests.get')
def test_buscar_usuario_sucesso(mock_get):
mock_get.return_value = MagicMock(status_code=200)
mock_get.return_value.json.return_value = {"id": 1, "nome": "João"}
resultado = buscar_usuario(1)
assert resultado["nome"] == "João"
mock_get.assert_called_once_with("https://api.example.com/users/1")
@patch('requests.get')
def test_buscar_usuario_erro(mock_get):
mock_get.return_value = MagicMock(status_code=404)
with pytest.raises(Exception):
buscar_usuario(1)</code></pre>
<p>O decorator <code>@patch</code> substitui a função real por um mock. Você controla o comportamento e verifica se as chamadas ocorreram corretamente. Isso torna testes rápidos e confiáveis, sem dependências externas.</p>
<h2>Testes End-to-End e Automação de Interface</h2>
<p>Testes end-to-end (E2E) simulam a jornada real do usuário, testando a aplicação completa do navegador até o banco de dados. <strong>Selenium</strong> e <strong>Playwright</strong> são frameworks populares para essa automação. Eles controlam navegadores reais, clicam em elementos e verificam resultados.</p>
<p>Aqui está um exemplo com Playwright em Python:</p>
<pre><code class="language-python">from playwright.sync_api import sync_playwright
def test_login_usuario():
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
Navegar até a aplicação
page.goto("https://exemplo.com/login")
Preencher formulário
page.fill("input[name='email']", "usuario@example.com")
page.fill("input[name='senha']", "senha123")
page.click("button:has-text('Entrar')")
Aguardar redirecionamento e verificar
page.wait_for_url("https://exemplo.com/dashboard")
assert page.is_visible("h1:has-text('Dashboard')")
browser.close()</code></pre>
<p>Testes E2E são lentos e frágeis se não bem estruturados — use-os para fluxos críticos. <strong>Dica profissional</strong>: mantenha seletores CSS descritivos e evite esperas fixas (use <code>wait_for_*</code> ao invés de <code>time.sleep()</code>).</p>
<h2>Boas Práticas e Estratégias Avançadas</h2>
<h3>Cobertura de Testes e Métricas</h3>
<p>A cobertura de testes indica qual percentual do código é executado durante testes. Use <code>coverage</code> em Python para medir:</p>
<pre><code class="language-bash">pip install coverage
coverage run -m pytest
coverage report
coverage html # Gera relatório HTML detalhado</code></pre>
<p>Busque <strong>80-90% de cobertura</strong> em código crítico, não 100% — é overkill e caro. Foque em lógica de negócio complexa.</p>
<h3>Estrutura AAA e Nomenclatura Clara</h3>
<p>Organize seus testes com a estrutura <strong>Arrange-Act-Assert</strong>:</p>
<pre><code class="language-python">def test_carrinho_adiciona_produto():
Arrange: preparar dados
carrinho = Carrinho()
produto = Produto("Notebook", 3000)
Act: executar ação
carrinho.adicionar(produto)
Assert: verificar resultado
assert len(carrinho.itens) == 1
assert carrinho.total == 3000</code></pre>
<p>Nomeie testes descritivamente: <code>test_[o_que_esta_sendo_testado]_[condicao]_[resultado_esperado]</code>.</p>
<h3>Testes Parametrizados</h3>
<p>Evite repetição usando parametrização:</p>
<pre><code class="language-python">import pytest
@pytest.mark.parametrize("entrada,esperado", [
(2, 4),
(3, 9),
(-1, 1),
])
def test_quadrado(entrada, esperado):
assert entrada ** 2 == esperado</code></pre>
<p>Um teste, múltiplos cenários. Isso torna suites de testes mais concisas e eficientes.</p>
<h2>Conclusão</h2>
<p>Testes automatizados são investimento essencial em qualidade e velocidade. <strong>Comece com testes unitários</strong> para lógica isolada, use <strong>mocks para integração</strong> sem dependências externas, e implemente <strong>E2E para fluxos críticos</strong>. Mantenha testes simples, legíveis e rápidos — uma suite lenta é um bloqueio ao desenvolvimento. Com disciplina, seus testes se tornarão documentação viva do comportamento esperado do sistema, permitindo refatorar com segurança e entregar valor continuamente.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://docs.pytest.org/" target="_blank" rel="noopener noreferrer">Pytest Documentation</a> — Documentação oficial do framework pytest</li>
<li><a href="https://docs.python.org/3/library/unittest.mock.html" target="_blank" rel="noopener noreferrer">Unittest Mock — Python Docs</a> — Guia completo de mocks em Python</li>
<li><a href="https://playwright.dev/python/" target="_blank" rel="noopener noreferrer">Playwright Documentation</a> — Framework para automação E2E</li>
<li><a href="https://testing-library.com/docs/" target="_blank" rel="noopener noreferrer">Testing Library Best Practices</a> — Princípios modernos de teste</li>
<li><a href="https://www.amazon.com.br/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627" target="_blank" rel="noopener noreferrer">Growing Object-Oriented Software, Guided by Tests</a> — Livro essencial sobre TDD</li>
</ul>