Por que QA não é etapa opcional: como testes técnicos sustentam a evolução de um projeto

Tecnologia··4 min de leitura
Por que QA não é etapa opcional: como testes técnicos sustentam a evolução de um projeto
Wendell Nunes Lima
Wendell Nunes Lima

@wendellnuneslima

Depois de cobrir stack, SEO técnico e arquitetura de dados da Nexus G, falta a camada que decide se tudo isso continua funcionando conforme o projeto cresce: QA. É comum tratar teste como etapa que se faz "se sobrar tempo", mas na prática é o contrário quanto mais a plataforma cresce, mais caro fica cada erro que só é descoberto depois que o usuário já encontrou.

O primeiro nível de teste que estruturei foi o unitário, focado em funções isoladas que não dependem de banco de dados nem de rede cálculo de slug de conteúdo, formatação de dado de perfil, validação de campo antes de salvar. Esse tipo de teste roda em milissegundos e serve como rede de segurança pra refatoração: quando eu mexo numa função utilitária compartilhada por vários pontos da aplicação, o teste unitário confirma na hora se algo quebrou, sem precisar navegar manualmente por cada tela que usa aquela função.

// slug.test.ts
import { generateSlug } from './slug';

test('gera slug a partir do título do conteúdo', () => {
  expect(generateSlug('Como a Nexus G nasceu!')).toBe('como-a-nexus-g-nasceu');
});

test('remove acentos e caracteres especiais', () => {
  expect(generateSlug('SEO técnico com Next.js')).toBe('seo-tecnico-com-nextjs');
});

O segundo nível é o de integração, que testa se as peças conversam direito entre si por exemplo, se uma chamada à API de criação de conteúdo realmente grava no Postgres respeitando as políticas de Row Level Security que detalhei no artigo sobre arquitetura de dados. É exatamente aqui que RLS mal configurado, que citei como "erro silencioso" no artigo anterior, é pego antes de virar problema em produção: o teste de integração simula o auth.uid() de um usuário específico e confirma que ele só consegue editar o próprio perfil, nunca o de outro.

test('usuário não pode editar conteúdo de outro perfil', async () => {
  const { error } = await supabaseAsUserA
    .from('contents')
    .update({ title: 'Alterado indevidamente' })
    .eq('profile_id', userBProfileId);

  expect(error).not.toBeNull();
});

O terceiro nível é o end-to-end, que simula o comportamento real de alguém navegando pela interface criar conta, publicar um conteúdo, ver ele aparecer no perfil público. Ferramentas como Playwright automatizam esse fluxo inteiro num navegador real, e esse tipo de teste é o que garante que a experiência do usuário continua funcionando de ponta a ponta, não só que cada peça isolada funciona sozinha. É comum um projeto ter cem por cento de cobertura em teste unitário e ainda assim quebrar em produção porque a integração entre as partes nunca foi validada de verdade o e2e existe justamente pra fechar essa lacuna.

test('usuário publica conteúdo e ele aparece no perfil público', async ({ page }) => {
  await page.goto('/login');
  await page.fill('#email', 'usuario@teste.com');
  await page.fill('#password', 'senha123');
  await page.click('button[type=submit]');

  await page.goto('/dashboard/novo-conteudo');
  await page.fill('#title', 'Artigo de teste e2e');
  await page.click('#publicar');

  await page.goto('/wendellnuneslima');
  await expect(page.getByText('Artigo de teste e2e')).toBeVisible();
});

Além dos três níveis clássicos, existe um quarto tipo que se conecta direto com o que já falei sobre performance: teste de regressão de Core Web Vitals. Rodar Lighthouse automaticamente a cada deploy, comparando LCP, INP e CLS com a versão anterior, evita que uma mudança aparentemente inofensiva uma nova fonte, um script de terceiro, uma imagem sem otimização derrube silenciosamente uma métrica que impacta ranqueamento. Sem esse teste automatizado, esse tipo de regressão só aparece semanas depois, quando o tráfego orgânico já caiu e fica muito mais difícil identificar qual mudança específica causou o problema.

O que amarra tudo isso é rodar essa bateria de testes dentro de um pipeline de integração contínua, disparado a cada alteração de código antes dela chegar em produção. Isso muda o papel do QA de "verificação manual feita por alguém depois que o código já está pronto" para "barreira automática que impede regressão de chegar ao usuário final". Na prática, cada camada de teste protege uma camada diferente do projeto: unitário protege a lógica isolada, integração protege a segurança e a comunicação entre partes, e2e protege a experiência real do usuário, e o teste de performance protege o resultado de negócio que todo esse trabalho técnico existe pra sustentar. Sem essa estrutura, cada nova funcionalidade vira um risco pra tudo que já estava funcionando e é exatamente esse risco que QA bem estruturado elimina antes que o usuário perceba.

Comentários

Entre com Google para comentar.

Mais de Wendell Nunes Lima

Wendell Nunes Lima

Escrito por

Wendell Nunes Lima

Fundador e Desenvolvedor da Nexus G

Especialista em desenvolvimento de plataformas digitais e fundador da Nexus G, um ecossistema criado para fortalecer a autoridade profissional com conteúdo otimizado para SEO e páginas preparadas para ranquear no Google.