Teste Unitário vs Teste de Integração vs Teste de Sistema: Qual a Diferença?

Ashley Goolam

Ashley Goolam

23 dezembro 2025

Teste Unitário vs Teste de Integração vs Teste de Sistema: Qual a Diferença?

A questão de teste unitário vs teste de integração vs teste de sistema às vezes confunde até mesmo desenvolvedores experientes. Esses três níveis de teste formam a base da qualidade do software, no entanto, as equipes frequentemente os utilizam de forma inadequada, criando suítes de teste que são superficiais demais ou impossivelmente caras de manter. Entender onde cada um se encaixa na sua estratégia de teste não é acadêmico, mas impacta diretamente a velocidade com que você pode entregar e a confiança que pode ter em seus lançamentos.

Este guia esclarecerá o escopo, o propósito e o momento de cada nível de teste, mostrando como eles funcionam juntos na pirâmide de testes, e também fornecerá exemplos práticos que você pode aplicar imediatamente. Enquanto você estiver desenvolvendo microsserviços, monólitos ou APIs, é essencial entender testes unitários vs testes de integração vs testes de sistema.

botão

O que é Teste Unitário?

O teste unitário valida as menores partes testáveis da sua aplicação — funções individuais, métodos ou classes — em completo isolamento. O objetivo é provar que cada unidade se comporta corretamente de acordo com sua especificação.

Escopo e Exemplo

Um teste unitário examina uma única peça de lógica sem dependências. Aqui está um exemplo simples:

// Function under test
function calculateDiscount(price, discountPercent) {
  if (discountPercent < 0 || discountPercent > 100) {
    throw new Error('Invalid discount percentage');
  }
  return price * (discountPercent / 100);
}

// Unit test
describe('calculateDiscount', () => {
  it('calculates 20% discount correctly', () => {
    expect(calculateDiscount(100, 20)).toBe(20);
  });
  
  it('throws error for negative discount', () => {
    expect(() => calculateDiscount(100, -5)).toThrow();
  });
});

Observe que o teste fornece entradas e verifica saídas diretamente — sem banco de dados, API ou interface de usuário envolvidos.

Prós e Contras

Prós:

Contras:

O que é Teste de Integração?

O teste de integração verifica se múltiplos componentes funcionam corretamente juntos. Ele se concentra nas interfaces entre as unidades — endpoints de API, conexões de banco de dados, filas de mensagens e interações de serviço.

Escopo e Exemplo

Aqui está um teste de integração para um endpoint de registro de usuário que interage com o banco de dados:

// Teste de integração para POST /api/users
describe('User Registration API', () => {
  it('creates user and stores in database', async () => {
    const userData = {
      name: 'Test User',
      email: 'test@example.com',
      password: 'ValidPass123'
    };
    
    // Ação: Chamar a API real
    const response = await axios.post('http://localhost:3000/api/users', userData);
    
    // Asserção: Verificar resposta E banco de dados
    expect(response.status).toBe(201);
    expect(response.data).toHaveProperty('userId');
    
    // Verificar estado do banco de dados
    const userInDb = await db.users.findByEmail('test@example.com');
    expect(userInDb).toBeTruthy();
    expect(userInDb.name).toBe('Test User');
  });
});

Este teste prova que a API, a lógica de negócio e a integração com o banco de dados funcionam juntas.

Prós e Contras

Prós:

Contras:

O que é Teste de Sistema?

O teste de sistema valida o sistema completo e integrado contra os requisitos de negócio. Ele trata a aplicação como uma caixa preta, testando fluxos de trabalho de ponta a ponta da perspectiva do usuário.

Escopo e Exemplo

Um teste de sistema para um fluxo de trabalho de compra de e-commerce:

// Teste de sistema: Fluxo de compra completo
describe('E-commerce Purchase System', () => {
  it('allows user to browse, add to cart, and checkout', async () => {
    // Passo 1: Registro do usuário
    const user = await api.register('shopper@example.com', 'password');
    
    // Passo 2: Navegar produtos
    const products = await api.searchProducts('laptop');
    expect(products.length).toBeGreaterThan(0);
    
    // Passo 3: Adicionar ao carrinho
    await api.addToCart(user.token, products[0].id, 1);
    
    // Passo 4: Finalizar compra
    const order = await api.checkout(user.token, {
      shippingAddress: '123 Main St',
      paymentMethod: 'visa'
    });
    
    // Oráculo: Verificar pedido completo
    expect(order.status).toBe('confirmed');
    expect(order.total).toBeGreaterThan(0);
    
    // Verificar efeitos colaterais
    const inventory = await api.getInventory(products[0].id);
    expect(inventory.stock).toBe(initialStock - 1);
  });
});

Isso abrange múltiplas APIs, bancos de dados e serviços externos (gateway de pagamento).

Prós e Contras

Prós:

Contras:

A Pirâmide de Testes de Software: Relação entre os Três

A pirâmide de testes visualiza como **teste unitário vs teste de integração vs teste de sistema** devem ser distribuídos:

        Testes de Sistema (10%)
            ▲
    Testes de Integração (30%)
            ▲
    Testes Unitários (60%)

Camada Inferior (Testes Unitários): Maior volume, execução mais rápida, executados constantemente
Camada Média (Testes de Integração): Volume moderado, validam integrações críticas
Camada Superior (Testes de Sistema): Menor volume, testam fluxos de trabalho de negócio centrais

Essa forma garante feedback rápido enquanto mantém a confiança. Inverta a pirâmide (muitos testes de sistema, poucos testes unitários) e sua suíte de testes se tornará lenta, frágil e cara.

pirâmide de testes de software

Quando Realizar Cada Teste: Integração no Ciclo de Vida

Fase de Desenvolvimento Tipo de Teste Principal Frequência Tempo de Execução
Escrita de código Testes unitários A cada salvamento < 1 segundo
Pull request Unitário + Integração Pré-commit 1-5 minutos
Pré-merge Integração + Sistema Selecionado Na aprovação do PR 5-15 minutos
Build noturno Suíte completa (todos os tipos) Diário 30-60 minutos
Pré-lançamento Testes de sistema + Testes de fumaça Antes da implantação 15-30 minutos
Produção Testes de fumaça + Monitoramento Contínuo Tempo real

Acertar o timing dos testes unitários vs testes de integração vs testes de sistema evita gargalos e garante que os portões de qualidade sejam significativos.

Tabela de Comparação: Escolhendo o Teste Certo

Fator Teste Unitário Teste de Integração Teste de Sistema
Velocidade ⚡⚡⚡ Muito Rápido ⚡⚡ Moderado ⚡ Lento
Isolamento Alto Médio Baixo
Capacidade de Depuração Fácil Moderado Difícil
Confiança Baixa Média Alta
Manutenção Baixa Média Alta
Quando Escrever Antes/durante a codificação Depois que as unidades funcionam Após a integração
Quem Escreve Desenvolvedores Desenvolvedores + QA QA + Desenvolvedores

Exemplo Prático: Testando um Endpoint de API

Vamos ver **teste unitário vs teste de integração vs teste de sistema** em ação para um endpoint `POST /api/users`:

Teste Unitário (Testando Lógica de Validação)

// Testar apenas a função de validação
describe('validateUser', () => {
  it('rejects invalid email', () => {
    const result = validateUser({ email: 'invalid' });
    expect(result.isValid).toBe(false);
    expect(result.errors).toContain('Invalid email format');
  });
});

Teste de Integração (Testando API + Banco de Dados)

// Testar camada de API com banco de dados real
describe('POST /api/users integration', () => {
  it('creates user in database', async () => {
    const response = await request(app)
      .post('/api/users')
      .send({ name: 'Test', email: 'test@example.com' });
    
    expect(response.status).toBe(201);
    
    // Oráculo: Verificar banco de dados
    const user = await db.users.findByEmail('test@example.com');
    expect(user.name).toBe('Test');
  });
});

Teste de Sistema (Testando Fluxo de Trabalho Completo)

// Testar registro → login → atualização de perfil
describe('User management system', () => {
  it('allows complete user lifecycle', async () => {
    // Registrar
    const reg = await api.post('/api/users', userData);
    expect(reg.status).toBe(201);
    
    // Login
    const login = await api.post('/api/auth/login', credentials);
    expect(login.data.token).toBeTruthy();
    
    // Atualizar perfil
    const update = await api.put('/api/users/me', updates, {
      headers: { Authorization: `Bearer ${login.data.token}` }
    });
    expect(update.status).toBe(200);
    
    // Verificar estado final
    const profile = await api.get('/api/users/me', {
      headers: { Authorization: `Bearer ${login.data.token}` }
    });
    expect(profile.data.name).toBe(updates.name);
  });
});

Como Apidog Ajuda Equipes de Desenvolvimento com Testes de API

Compreender teste unitário vs teste de integração vs teste de sistema é crucial, mas implementá-los para APIs pode ser tedioso. Apidog automatiza o trabalho pesado, especialmente para testes de integração e de sistema.

Geração Automática de Oráculos de Teste

Para testes de integração, o Apidog cria oráculos de teste diretamente da sua especificação OpenAPI:

# Da sua especificação de API, Apidog gera:
Teste: POST /api/users
Oráculo 1: O Status deve ser 201
Oráculo 2: A Resposta deve corresponder ao esquema do Usuário
Oráculo 3: O cabeçalho Location deve existir
Oráculo 4: Tempo de resposta < 500ms
Oráculo 5: A consulta ao banco de dados retorna o usuário criado

Isso elimina a definição manual de oráculos e mantém os testes sincronizados com o seu contrato de API.

Construtor Visual de Testes para Testes de Sistema

Testar fluxos de trabalho complexos se torna visual no Apidog:

Teste: Fluxo Completo de Onboarding de Usuário
1. POST /api/users (criar)
2. POST /api/auth/verify (verificação de e-mail)
3. POST /api/auth/login (autenticar)
4. GET /api/dashboard (carregar dados)
5. POST /api/preferences (definir preferências)

Asserções em cada passo + validação do estado final

Você constrói isso arrastando e soltando chamadas de API, com o Apidog lidando com autenticação, encadeamento de dados e asserções automaticamente.

botão
testando no apidog

Integração CI/CD para Testes Contínuos

Apidog executa sua hierarquia de **teste unitário vs teste de integração vs teste de sistema** em CI/CD:

# Pipeline do GitHub Actions
- name: Executar Testes Unitários
  run: npm test:unit

- name: Executar Testes de Integração Apidog
  run: apidog run --tags "@integration"

- name: Executar Testes de Sistema Apidog
  run: apidog run --tags "@system"

Isso garante que cada tipo de teste seja executado na etapa apropriada com resultados publicados diretamente no Slack ou e-mail.

ci/cd no apidog

Visibilidade da Cobertura de Testes

Apidog mostra quais APIs possuem cobertura de teste unitário, de integração e de sistema:

Endpoint Unitário Integração Sistema Cobertura
POST /users 100%
GET /users/:id 67%
DELETE /users 67%

Essa visibilidade ajuda as equipes a preencher lacunas de teste estrategicamente.

Perguntas Frequentes

P1: Devo escrever testes unitários para endpoints de API?

Resp: Endpoints de API orquestram a lógica — eles devem ter testes de integração. A lógica de negócio dentro dos endpoints deve ser testada unitariamente separadamente.

P2: Quantos testes de integração são suficientes?

Resp: Cubra todos os caminhos críticos e cenários de erro. Uma boa regra: se um bug na integração pudesse chegar à produção, escreva um teste para ele.

P3: Testes de sistema valem o custo de manutenção?

Resp: Sim, mas apenas para fluxos de trabalho de negócio centrais. Limite os testes de sistema a 10-20% das funcionalidades que geram 80% do valor de negócio.

P4: O Apidog pode gerar testes unitários?

Resp: Não. Testes unitários requerem conhecimento da estrutura interna do código. Apidog se destaca em testes de integração e de sistema, onde pode observar o comportamento da API externamente.

P5: Qual tipo de teste devo priorizar para um novo projeto?

Resp: Comece com testes unitários (fundação), adicione testes de integração à medida que os componentes se conectam, e então adicione testes de sistema para jornadas críticas do usuário. Essa abordagem de pirâmide previne dívida técnica.

Conclusão

A decisão entre teste unitário vs teste de integração vs teste de sistema não se trata de escolher um em detrimento do outro — mas sim de aplicar cada um no momento e proporção certos. Testes unitários proporcionam velocidade e precisão para o desenvolvimento. Testes de integração detectam problemas de conexão que os testes unitários não conseguem. Testes de sistema fornecem confiança de que o produto completo funciona para os usuários.

Domine essa hierarquia e sua suíte de testes se tornará um ativo estratégico em vez de um fardo de manutenção. Comece auditando sua distribuição atual de testes. Você está invertido com muitos testes de sistema lentos e frágeis? Mude o foco para baixo. Está faltando cobertura de integração crítica? Preencha essas lacunas.

Ferramentas modernas como o Apidog tornam as camadas de integração e sistema muito mais gerenciáveis, automatizando a criação e execução de testes. Isso permite manter o formato da pirâmide de testes sem diminuir a velocidade de desenvolvimento. A qualidade se torna um resultado natural do seu processo, não uma fase separada que atrasa os lançamentos.

Lembre-se: o objetivo não é testar tudo — mas sim testar as coisas certas no nível certo. Quando **teste unitário vs teste de integração vs teste de sistema** está claro em sua estratégia, a entrega se torna previsível, a confiança aumenta, e sua equipe gasta menos tempo combatendo incêndios e mais tempo construindo valor.

botão

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs