Um expect() padrão para o teste na primeira falha. Um formulário com quatro mensagens de validação quebradas precisa de quatro execuções de teste para diagnosticar completamente. expect.soft() coleta todas as falhas e as reporta juntas no final, mas o teste ainda falha se alguma soft assertion falhou: ele continua rodando, não passando.
Como as soft assertions funcionam
import { test, expect } from '@playwright/test';
test('página de perfil do usuário tem todos os elementos obrigatórios', async ({ page }) => {
await page.goto('/profile');
// Soft assertions — todas rodam mesmo que algumas falhem
await expect.soft(page.getByLabel('Full name')).toBeVisible();
await expect.soft(page.getByLabel('Email')).toBeVisible();
await expect.soft(page.getByLabel('Phone number')).toBeVisible();
await expect.soft(page.getByRole('button', { name: 'Save changes' })).toBeEnabled();
await expect.soft(page.getByRole('img', { name: 'Profile photo' })).toBeVisible();
// É aqui que o teste realmente falha — se alguma soft assertion acima falhou
expect(test.info().errors).toHaveLength(0);
});Cada expect.soft() roda. As falhas são coletadas. O teste continua. No final (ou quando você verifica test.info().errors), todas as falhas são reportadas de uma vez.
Assertions hard vs. soft
Use assertions hard (expect) quando:
- Uma falha torna o resto do teste sem sentido (ex.: login falhou, nada mais funciona)
- Você está verificando uma pré-condição, não um resultado
- Uma falha implica logicamente outras (navegação falhou, nada na página importa)
Use soft assertions (expect.soft) quando:
- Você está verificando múltiplas propriedades independentes da mesma página
- Cada falha é informação de debug independentemente útil
- Você está verificando que um formulário, linha de tabela ou card tem todos os seus campos
test('confirmação de pedido exibe todos os detalhes', async ({ page }) => {
await page.goto('/orders/12345');
// Assertion hard — se isso falhar, nada mais importa
await expect(page.getByRole('heading', { name: 'Order #12345' })).toBeVisible();
// Soft assertions — verificações independentes, todas úteis
await expect.soft(page.getByText('Status: Confirmed')).toBeVisible();
await expect.soft(page.getByText('Delivery: 2–5 business days')).toBeVisible();
await expect.soft(page.getByText('Total: $149.99')).toBeVisible();
await expect.soft(page.getByRole('button', { name: 'Track order' })).toBeEnabled();
await expect.soft(page.getByRole('button', { name: 'Cancel order' })).toBeEnabled();
});Lendo falhas de soft assertions
Quando uma soft assertion falha, o Playwright reporta todas as falhas juntas:
Error: 2 soft assertion(s) failed.
1) Soft assertion failed: expect(locator).toBeVisible()
Call log:
- waiting for page.getByText('Status: Confirmed')
Error: expect(locator).toBeVisible() with timeout 5000ms
Received: hidden
2) Soft assertion failed: expect(locator).toBeEnabled()
Call log:
- waiting for page.getByRole('button', { name: 'Cancel order' })
Error: expect(locator).toBeEnabled() with timeout 5000ms
Received: disabledDois problemas em uma execução, não um problema por execução.
Soft assertions em testes de validação de formulário
Validação de formulário é um caso de uso clássico: muitos estados de erro para verificar, todos independentes.
test('formulário mostra todos os erros de validação ao submeter vazio', async ({ page }) => {
await page.goto('/register');
await page.getByRole('button', { name: 'Create account' }).click();
// Verifica que todas as mensagens de validação aparecem
await expect.soft(page.getByText('Email is required')).toBeVisible();
await expect.soft(page.getByText('Password is required')).toBeVisible();
await expect.soft(page.getByText('First name is required')).toBeVisible();
await expect.soft(page.getByText('Last name is required')).toBeVisible();
// Verifica que o botão de submit ainda está disponível (não desabilitado após falha)
await expect.soft(page.getByRole('button', { name: 'Create account' })).toBeEnabled();
});Sem soft assertions, você saberia da primeira mensagem faltando e teria que rodar o teste mais três vezes para encontrar todos os quatro problemas.
Verificando erros explicitamente
Você pode verificar falhas de soft assertions em qualquer ponto do teste:
test('verificação de completude da página de produto', async ({ page }) => {
await page.goto('/products/laptop-pro');
// Seção 1: Seção hero
await expect.soft(page.getByRole('heading', { level: 1 })).toBeVisible();
await expect.soft(page.getByRole('img', { name: /product/i })).toBeVisible();
await expect.soft(page.getByText(/\$\d+\.\d{2}/)).toBeVisible(); // Preço
// Se a seção hero tem falhas, para aqui — não faz sentido verificar o resto
if (test.info().errors.length > 0) {
test.fail();
return;
}
// Seção 2: Só roda se a hero passou
await expect.soft(page.getByRole('button', { name: 'Add to cart' })).toBeEnabled();
await expect.soft(page.getByRole('tab', { name: 'Reviews' })).toBeVisible();
await expect.soft(page.getByRole('tab', { name: 'Specifications' })).toBeVisible();
});Misturando assertions hard e soft
O padrão mais eficaz: assertions hard para pré-condições e estado crítico, soft assertions para propriedades individuais:
test('dashboard carrega todos os widgets', async ({ page }) => {
await page.goto('/dashboard');
// Hard — se isso falhar, a página não carregou de forma alguma
await expect(page).toHaveTitle(/Dashboard/);
await expect(page.getByRole('main')).toBeVisible();
// Soft — cada widget é independente
await expect.soft(page.getByTestId('revenue-widget')).toBeVisible();
await expect.soft(page.getByTestId('orders-widget')).toBeVisible();
await expect.soft(page.getByTestId('users-widget')).toBeVisible();
await expect.soft(page.getByTestId('activity-feed')).toBeVisible();
// Soft — cada métrica é independente
await expect.soft(page.getByTestId('revenue-amount')).toContainText('$');
await expect.soft(page.getByTestId('orders-count')).toContainText(/\d+/);
});Quando não usar soft assertions
Soft assertions coletam falhas mas deixam o teste continuar. Isso pode mascarar problemas de estado:
// Perigoso — se o clique não funcionou, as assertions abaixo testam o estado errado
await expect.soft(page.getByRole('button', { name: 'Submit' })).toBeEnabled();
await page.getByRole('button', { name: 'Submit' }).click();
await expect.soft(page.getByText('Order confirmed')).toBeVisible(); // pode passar acidentalmenteSe ações dependem de assertions anteriores passando, use assertions hard. Soft assertions são para observação (verificar o que está na página), não para controle de fluxo.
→ Veja também: Assertions no Playwright: O Guia Completo | Estrutura de Testes no Playwright: describe, beforeEach, afterEach e Hooks | Como Ler Mensagens de Erro do Playwright