Testes Automatizados em ERP: Estratégias da Unidade ao Negócio

Testes Automatizados em ERP: Estratégias da Unidade ao Negócio
“Qualidade não é um ato, é um hábito.” – Philip Crosby
Em ambientes corporativos, um ERP (Enterprise Resource Planning) é o coração dos processos de negócio. Qualquer falha pode gerar perdas financeiras, retrabalho e danos à reputação. Por isso, a automação de testes deixa de ser opcional e passa a ser estratégica. Neste artigo, vamos explorar como planejar, executar e mensurar testes automatizados em um ERP, cobrindo desde testes de unidade até fluxos de negócio completos, passando por ferramentas, métricas de cobertura e integração contínua.
1. Introdução
Um ERP típico reúne módulos como Financeiro, Estoque, Vendas, RH e Produção, todos interdependentes. Essa complexidade gera dois grandes desafios:
A resposta está nos testes automatizados, que permitem validar rapidamente cada camada do sistema e reduzir o risco de regressões. Mas, para que a automação seja efetiva, é preciso seguir uma estratégia estruturada, escolher as ferramentas adequadas e medir a cobertura de forma objetiva.
Objetivo deste guia: apresentar um plano de ação prático, com exemplos de código em Python, que pode ser adaptado a qualquer stack tecnológica.
2. Estratégias de Cobertura de Testes
2.1. Pirâmide de Testes Adaptada ao ERP
A pirâmide tradicional (unidade, integração, UI) precisa de ajustes para refletir a realidade de um ERP:
| Nível | Propósito | Ferramentas recomendadas |
|---|---|---|
| Teste de Unidade | Validar lógica de classes, funções e regras de negócio isoladas. | pytest, unittest, factory_boy |
| Teste de Serviço | Verificar contratos entre módulos (ex.: API interna, eventos de fila). | requests, responses, pytest-mock |
| Teste de Fluxo de Negócio | Simular cenários reais (ex.: criação de pedido → faturamento). | behave, pytest-bdd, robotframework |
| Teste de Performance (opcional) | Avaliar tempo de resposta em picos de carga. | locust, k6 |
Dica: Priorize a base da pirâmide (unidade) – 70 % dos testes devem estar aqui. Fluxos de negócio são mais custosos, mas críticos para validar integrações entre módulos.
2.2. Métricas de Cobertura
Apenas “percentual de linhas cobertas” pode ser enganoso. Considere:
| Métrica | Como medir | Por que importa |
|---|---|---|
| Cobertura de linhas | coverage run + coverage report | Indica quanto do código foi executado pelos testes. |
| Cobertura de branches | coverage -b | Detecta caminhos não testados em estruturas condicionais. |
| Cobertura de requisitos | Mapeamento de casos de teste ↔️ requisitos (planilha ou ferramenta de gestão). | Garante que todas as regras de negócio foram verificadas. |
| Taxa de falhas regressivas | % de builds que falham após mudança de código. | Avalia a eficácia dos testes em prevenir regressões. |
3. Ferramentas Essenciais para um ERP
3.1. Framework de Testes
pytest– sintaxe concisa, fixtures poderosas e plugins (ex.:pytest-covpara cobertura,pytest-xdistpara paralelismo).factory_boy– geração de objetos de domínio (ex.: clientes, produtos) de forma rápida e consistente.behave– BDD (Behavior‑Driven Development) para descrever fluxos de negócio em linguagem natural.
3.2. Integração Contínua (CI)
Um pipeline CI/CD automatiza a execução dos testes a cada commit. Exemplos de provedores:
| Provedor | Configuração mínima | Benefício |
|---|---|---|
| GitHub Actions | Arquivo .github/workflows/ci.yml | Integração nativa com repositórios GitHub. |
| GitLab CI | .gitlab-ci.yml | Suporte a runners auto‑hospedados. |
| Azure Pipelines | azure-pipelines.yml | Ideal para ambientes Microsoft. |
3.3. Relatórios de Qualidade
allure-pytest– gera relatórios HTML ricos, com screenshots, logs e etapas detalhadas.sonarqube– análise estática de código e métricas de cobertura centralizadas.
4. Desenvolvimento da Estratégia de Testes
4.1. Mapeamento de Requisitos
Ferramenta sugerida: Jira ou Azure Boards com campos customizados para rastrear a ligação entre requisito e teste.
4.2. Criação de Fixtures e Dados de Teste
Para um ERP, os dados de teste precisam refletir a realidade (catálogos de produtos, tabelas de impostos, usuários com diferentes perfis). Use factory_boy para gerar esses objetos de forma programática.
# tests/factories.py
import factory
from datetime import date
from myerp.models import Cliente, Produto, Pedido
class ClienteFactory(factory.Factory):
class Meta:
model = Cliente
nome = factory.Faker('name')
email = factory.Faker('email')
tipo = 'PF' # Pessoa Física
class ProdutoFactory(factory.Factory):
class Meta:
model = Produto
codigo = factory.Sequence(lambda n: f"P{1000 + n}")
descricao = factory.Faker('sentence')
preco = factory.Faker('pydecimal', left_digits=4, right_digits=2, positive=True)
class PedidoFactory(factory.Factory):
class Meta:
model = Pedido
cliente = factory.SubFactory(ClienteFactory)
data = date.today()
status = 'ABERTO'
4.3. Teste de Unidade – Exemplo
Vamos validar a regra de cálculo de desconto no módulo de Vendas.
# tests/unit/test_desconto.py
import pytest
from myerp.services.desconto import calcula_desconto
@pytest.mark.parametrize(
"valor,total,esperado",
[
(1000, 0, 0), # sem histórico, sem desconto
(1000, 5000, 0.05), # histórico acima de 5k → 5% de desconto
(2000, 20000, 0.10), # histórico acima de 20k → 10% de desconto
]
)
def test_calcula_desconto(valor, total, esperado):
assert calcula_desconto(valor, total) == pytest.approx(esperado)
4.4. Teste de Serviço – Simulando Integração entre Módulos
Suponha que o módulo de Estoque exponha um endpoint /api/estoque/reserva. O módulo de Vendas consome esse serviço para reservar itens ao criar um pedido.
# tests/service/test_reserva_estoque.py
import json
import pytest
import requests
from unittest import mock
API_URL = "http://localhost:8000/api/estoque/reserva"
def mock_reserva_success(args, kwargs):
class Resp:
status_code = 200
def json(self):
return {"status": "OK", "quantidade_reservada": kwargs["json"]["quantidade"]}
return Resp()
@mock.patch('requests.post', side_effect=mock_reserva_success)
def test_reserva_estoque_sucesso(mock_post):
payload = {"produto_id": 101, "quantidade": 5}
response = requests.post(API_URL, json=payload)
assert response.status_code == 200
data = response.json()
assert data["status"] == "OK"
assert data["quantidade_reservada"] == 5
mock_post.assert_called_once_with(API_URL, json=payload)
4.5. Teste de Fluxo de Negócio – BDD com Behave
Cenário: “Criar pedido → gerar nota fiscal → atualizar estoque”*.
# features/fluxo_pedido.feature
Funcionalidade: Fluxo completo de pedido
Como vendedor
Quero criar um pedido e garantir que a nota fiscal seja emitida e o estoque atualizado
Cenário: Pedido com sucesso
Dado que exista um cliente cadastrado
E que existam 10 unidades do produto "Caneta" em estoque
Quando eu criar um pedido de 3 unidades desse produto
Então a nota fiscal deve ser emitida
E o estoque deve ficar com 7 unidades
```python
features/steps/pedido_steps.py
from behave import given, when, then from myerp.models import Cliente, Produto, Pedido, NotaFiscal from myerp.services import estoque, faturamento
@given('que exista um cliente cadastrado') def step_impl(context): context.cliente = ClienteFactory()
@given('que existam {qtde:d} unidades do produto "{nome}" em estoque') def step_impl(context, qtde, nome): context.produto = ProdutoFactory(descricao=nome) estoque.adicionar(context.produto.id, qtde)
@when('eu criar um pedido de {qtde:d} unidades desse produto') def step


