← Escrita
    Rodrigo Oliveira Cabral··9 min de leitura

    Não basta construir rápido: o que o Playwright ensina sobre validar antes de escalar

    Janela de browser dividida: à esquerda um teste Playwright em execução, à direita sinais de mercado a entrar num painel da Painstack, com a frase Test the product. Validate the problem.

    Automatizar testes não prova que o mercado quer um produto. Mas ajuda a garantir que, quando alguém decide usá-lo, a experiência funciona como prometido.

    Durante muito tempo, pensei nos testes automatizados como uma etapa essencialmente técnica: escrever código, simular ações e verificar se a aplicação responde como deveria.

    Essa definição continua correta, mas hoje considero-a incompleta.

    Uma aplicação pode funcionar perfeitamente e ainda assim resolver o problema errado. Da mesma forma, uma equipa pode ter identificado um problema real e perder utilizadores porque o fluxo principal falha no browser, num dispositivo móvel ou após uma alteração aparentemente pequena.

    Foi por isso que o Playwright me chamou a atenção.

    Não apenas por automatizar browsers, mas porque materializa uma ideia que também está no centro do trabalho que fazemos na Painstack:

    Não devemos confiar numa suposição quando podemos testá-la.

    No desenvolvimento de software, testamos o comportamento da aplicação.

    Na construção de um negócio, validamos a existência e a relevância do problema.

    São camadas diferentes de evidência. Um teste não substitui o outro.

    O que é o Playwright?

    O Playwright é uma framework open-source para testes end-to-end de aplicações web.

    Um teste end-to-end reproduz um percurso completo pela perspetiva do utilizador. Em vez de verificar apenas uma função isolada, podemos abrir a aplicação, preencher um formulário, clicar num botão e confirmar se o resultado esperado aparece.

    Segundo a documentação oficial, o Playwright suporta:

    • Chromium;
    • Firefox;
    • WebKit;
    • Windows, Linux e macOS;
    • execução local ou em CI;
    • modo visual ou headless;
    • emulação de diferentes dispositivos móveis.

    O Playwright Test também inclui o executor de testes, asserções, isolamento entre testes, paralelização, relatórios e ferramentas de diagnóstico.

    Isso permite que a equipa se concentre menos na infraestrutura de automação e mais nos comportamentos que realmente precisa de proteger.

    O meu primeiro princípio: testar o percurso, não a implementação

    Um dos erros mais comuns na automação é criar testes demasiado ligados à estrutura interna da página.

    Imagine um botão com esta implementação:

    <button class="button-primary blue large">
      Começar validação
    </button>
    

    Poderíamos localizá-lo através da sua classe CSS:

    await page.locator('.button-primary.blue.large').click();
    

    O problema é que uma alteração visual pode quebrar o teste, mesmo que a experiência continue correta.

    O Playwright incentiva localizadores mais próximos da forma como o utilizador e as tecnologias assistivas interpretam a página:

    await page
      .getByRole('button', { name: 'Começar validação' })
      .click();
    

    Neste caso, o teste não está interessado na cor ou no nome interno da classe. Está a verificar se existe um botão identificável com a ação esperada.

    Essa distinção é importante.

    Um teste útil deve proteger um contrato de experiência, não congelar todos os detalhes da implementação.

    Um primeiro teste com Playwright

    Num projeto Node.js, podemos iniciar a configuração com:

    npm init playwright@latest
    

    Durante a instalação, o Playwright permite escolher TypeScript ou JavaScript, definir a pasta dos testes e instalar os browsers necessários.

    Depois disso, podemos criar um teste simples:

    import { test, expect } from '@playwright/test';
    
    test('a página principal apresenta a ação de validação', async ({ page }) => {
      await page.goto('https://usepainstackai.com/');
    
      await expect(page).toHaveTitle(/Painstack/i);
    
      const validationCta = page
        .getByRole('link', { name: /validate/i })
        .first();
    
      await expect(validationCta).toBeVisible();
    });
    

    O teste abre o site da Painstack e verifica duas condições básicas:

    1. O título da página identifica o produto;
    2. A ação principal de validação está visível para o utilizador.

    É um exemplo simples, mas representa um comportamento importante.

    Se a página carregar sem o seu principal call to action, pode estar tecnicamente online e, ao mesmo tempo, falhar na sua função.

    Auto-waiting: esperar por condições, não por segundos

    Interfaces modernas nem sempre respondem de forma imediata.

    Um elemento pode depender de JavaScript, de uma chamada à API ou de uma animação. Em ferramentas mais antigas, era comum encontrar pausas manuais como esta:

    await page.waitForTimeout(3000);
    

    Esse tipo de espera é frágil.

    Se a aplicação responder em 500 milissegundos, o teste desperdiça tempo. Se responder em quatro segundos, o teste pode falhar mesmo sem existir um problema funcional.

    O Playwright aplica verificações de actionability antes de executar ações. Antes de clicar, por exemplo, confirma condições como visibilidade, estabilidade e capacidade de interação do elemento.

    Também oferece asserções assíncronas:

    await expect(
      page.getByText('Análise concluída')
    ).toBeVisible();
    

    Em vez de esperar arbitrariamente por três segundos, o teste espera pela condição que realmente interessa.

    Isso não elimina automaticamente todos os testes instáveis. Mas reduz a necessidade de sincronização manual e ajuda a escrever verificações mais próximas do comportamento real da interface.

    Cada teste começa num ambiente isolado

    Outro ponto relevante é o isolamento.

    O Playwright utiliza Browser Contexts, comparáveis a perfis novos e independentes do browser. Cada teste pode começar sem cookies, sessões ou estado deixado pelo teste anterior.

    Por exemplo:

    test('utilizador não autenticado vê a opção de login', async ({ page }) => {
      await page.goto('/');
    
      await expect(
        page.getByRole('link', { name: /entrar|login/i })
      ).toBeVisible();
    });
    

    Outro teste pode utilizar um estado autenticado próprio, sem depender da execução anterior.

    Essa independência tem duas vantagens:

    • os testes podem ser executados em paralelo;
    • uma falha tende a ser mais fácil de reproduzir.

    Quando o teste B só funciona depois do teste A, a suite deixa de representar utilizadores independentes e passa a depender da ordem de execução.

    Testar em mais de um browser

    Uma aplicação que funciona em Chromium não está automaticamente validada em todos os browsers.

    O Playwright permite configurar diferentes projetos no ficheiro playwright.config.ts:

    import { defineConfig, devices } from '@playwright/test';
    
    export default defineConfig({
      testDir: './tests',
    
      projects: [
        {
          name: 'chromium',
          use: { ...devices['Desktop Chrome'] },
        },
        {
          name: 'firefox',
          use: { ...devices['Desktop Firefox'] },
        },
        {
          name: 'webkit',
          use: { ...devices['Desktop Safari'] },
        },
        {
          name: 'mobile',
          use: { ...devices['iPhone 13'] },
        },
      ],
    });
    

    A mesma suite pode então verificar o comportamento em diferentes motores de browser e numa configuração móvel.

    O objetivo não deve ser criar uma matriz enorme sem critério. O mais sensato é começar pelos ambientes usados pelo público e pelos percursos com maior impacto.

    Cobertura técnica sem prioridade de produto transforma-se facilmente em custo de manutenção.

    Quando um teste falha, o Trace Viewer mostra o contexto

    Uma mensagem de erro isolada nem sempre explica o que aconteceu.

    O Trace Viewer permite analisar a execução passo a passo. Podemos observar o estado da página antes e depois de cada ação e consultar:

    • screenshots;
    • logs;
    • pedidos de rede;
    • erros;
    • mensagens da consola;
    • código-fonte associado à ação;
    • snapshots do DOM.

    Uma configuração possível é guardar o trace na primeira repetição de um teste:

    import { defineConfig } from '@playwright/test';
    
    export default defineConfig({
      use: {
        trace: 'on-first-retry',
      },
    });
    

    Isto é particularmente útil em integração contínua. Se um teste falhar fora da máquina do programador, o trace oferece muito mais contexto do que uma mensagem genérica no terminal.

    Não substitui uma investigação cuidadosa, mas reduz a quantidade de adivinhação necessária.

    O que devemos testar primeiro?

    É fácil cair na tentação de automatizar tudo.

    Eu prefiro começar por uma pergunta mais concreta:

    Que falha impediria o utilizador de obter o valor principal do produto?

    Numa aplicação SaaS, a primeira suite pode proteger percursos como:

    1. A página principal carrega;
    2. A proposta de valor e a ação principal estão visíveis;
    3. O utilizador consegue criar uma conta ou entrar;
    4. O fluxo central aceita os dados necessários;
    5. O sistema apresenta um estado de progresso compreensível;
    6. O resultado final pode ser consultado;
    7. Erros de validação são apresentados de forma clara;
    8. Os percursos essenciais funcionam em desktop e mobile.

    Só depois faz sentido expandir para variações, casos extremos e regressões menos críticas.

    Esta priorização aproxima a estratégia de testes da estratégia de produto. Não testamos uma funcionalidade apenas porque existe. Testamo-la porque existe um comportamento importante que não queremos perder.

    Playwright não valida se alguém precisa do produto

    Esta é a distinção que considero mais importante.

    O Playwright consegue confirmar que:

    • o botão aparece;
    • o formulário aceita dados válidos;
    • a navegação chega ao destino esperado;
    • o resultado é apresentado;
    • o percurso funciona em diferentes browsers.

    Mas não consegue provar que:

    • o problema é frequente;
    • o problema é suficientemente importante;
    • o público procura uma alternativa;
    • a proposta de valor é compreendida;
    • alguém pagaria pela solução.

    Essas perguntas exigem outro tipo de evidência: entrevistas, padrões de procura, discussões em comunidades, alternativas existentes, comportamento de utilização e sinais de mercado.

    É precisamente nesta camada anterior ao desenvolvimento que a Painstack atua: organizar evidências sobre um problema antes de transformar uma hipótese numa grande aposta de produto.

    Podemos resumir assim:

    A validação de mercado ajuda-nos a decidir o que vale a pena construir. O Playwright ajuda-nos a verificar se aquilo que construímos continua a funcionar.

    Ter apenas uma das duas partes deixa uma lacuna.

    Sem validação do problema, corremos o risco de entregar software estável que ninguém precisava.

    Sem testes do produto, podemos identificar uma necessidade real e oferecer uma experiência que falha no momento decisivo.

    Testes são evidência executável

    Gosto de pensar num teste automatizado como uma afirmação executável.

    Quando escrevemos:

    await expect(validationCta).toBeVisible();
    

    estamos a declarar que a presença dessa ação faz parte do contrato atual do produto.

    A cada execução, essa afirmação é novamente verificada contra a aplicação real.

    Isso não significa que o teste seja uma verdade permanente. O produto pode mudar, o contrato pode evoluir e o próprio teste pode estar errado. Mas obriga-nos a tornar explícito o comportamento esperado.

    O mesmo princípio aplica-se à criação de produtos.

    Uma hipótese escrita é melhor do que uma intuição vaga. Uma hipótese confrontada com evidências é melhor do que uma hipótese apenas bem apresentada.

    Playwright e Painstack operam em pontos distintos do processo, mas partilham uma disciplina: transformar expectativas implícitas em verificações observáveis.

    Conclusão

    O Playwright é uma opção relevante para equipas que precisam de testar aplicações web modernas em diferentes browsers, com isolamento, esperas automáticas e ferramentas visuais de diagnóstico.

    Mas a sua maior utilidade não está em aumentar artificialmente o número de testes.

    Está em proteger os percursos que sustentam a experiência prometida ao utilizador.

    Antes de automatizar, precisamos de escolher o comportamento certo.

    Antes de construir, precisamos de validar o problema certo.

    Nos dois casos, o objetivo não é eliminar totalmente a incerteza. É reduzir decisões baseadas apenas em confiança, opinião ou memória.

    Construir rápido continua a ser importante.

    Saber o que testar — e o que vale a pena construir — é ainda mais importante.


    Referências

    PlaywrightTestes E2EValidação de produtoPainstack

    Queres acompanhar o que aprendo pelo caminho?

    Escrevo sobre os desafios, decisões e aprendizagens de construir projetos, incluindo os recursos e métodos que me têm ajudado. Subscreve a newsletter e recebe os próximos artigos diretamente no teu email.

    Sem spam. Cancelas quando quiseres. Privacidade