Um teste de UI que clica em "Fazer Pedido" e vê uma tela de confirmação não te diz se o pedido foi realmente gravado no banco de dados. SQL faz isso.
Por que engenheiros de QA precisam de SQL
Testes de UI verificam o que o usuário vê. SQL verifica o que realmente aconteceu.
Quando um teste clica em "Fazer Pedido" e vê uma tela de confirmação, você sabe que a UI respondeu. Não sabe se o pedido foi salvo. Não sabe se o status correto foi definido. Não sabe se a chave estrangeira foi gravada corretamente. A única forma de verificar isso é olhar direto no banco de dados.
Casos de uso de SQL no QA:
- Verificar que os dados foram salvos após uma ação de UI (submit de formulário, upload de arquivo, pagamento)
- Configurar dados de teste diretamente em vez de fazer 10 cliques na UI
- Verificar dados que a UI não expõe (logs de auditoria, flags internos, registros soft-deleted)
- Reproduzir bugs verificando em que estado o banco estava quando algo falhou
- Validar migrações depois que um deploy mudou o schema
Quando uma vaga diz "experiência com SQL necessária", é isso que eles querem dizer. Não stored procedures, não otimização de queries, não administração de banco de dados. Instruções SELECT com condições.
A ferramenta: qualquer cliente SQL
Você não precisa conhecer um produto de banco de dados específico. A sintaxe de queries é quase idêntica entre PostgreSQL, MySQL e SQLite. Para praticar:
- TablePlus (Mac/Windows): interface limpa, plano gratuito é suficiente
- DBeaver: gratuito, funciona com todos os tipos de banco de dados
- psql: linha de comando do PostgreSQL, sempre disponível
- Qualquer teste Playwright com um pacote
pgoumysql2também pode rodar queries diretamente
Para os exemplos abaixo, a estrutura é baseada no schema do banco de dados do lab.becomeqa.com.
Padrão 1: SELECT
A coisa mais comum que você vai fazer:
-- Obter todos os usuários
SELECT * FROM users;
-- Obter colunas específicas
SELECT id, email, created_at FROM users;
-- Obter um usuário pelo email
SELECT * FROM users WHERE email = 'admin@becomeqa.com';
-- Obter usuários criados nos últimos 7 dias
SELECT * FROM users WHERE created_at > NOW() - INTERVAL '7 days';SELECT * obtém todas as colunas. SELECT id, email obtém apenas essas colunas. WHERE filtra linhas. Isso é 90% do que você precisa.
No contexto do QA:
-- Após um teste de registro, verificar que o usuário foi criado
SELECT id, email, role, is_active
FROM users
WHERE email = 'testuser_1234567@test.com';Se retornar uma linha, o usuário foi salvo. Se não retornar nada, o registro falhou silenciosamente mesmo que a UI tenha mostrado sucesso.
Padrão 2: WHERE com condições
Combinando condições:
-- AND: ambas as condições devem ser verdadeiras
SELECT * FROM items
WHERE status = 'completed' AND user_id = 42;
-- OR: qualquer condição deve ser verdadeira
SELECT * FROM items
WHERE status = 'pending' OR status = 'in_progress';
-- IN: corresponder a qualquer valor de uma lista
SELECT * FROM items
WHERE status IN ('pending', 'in_progress', 'completed');
-- NOT: excluir linhas
SELECT * FROM items WHERE status != 'deleted';
-- LIKE: correspondência parcial de string (% é curinga)
SELECT * FROM users WHERE email LIKE '%@test.com';
-- IS NULL: verificar valores ausentes
SELECT * FROM items WHERE deleted_at IS NULL;
SELECT * FROM items WHERE deleted_at IS NOT NULL;-- Verificar que o soft-delete funcionou (deleted_at deve estar preenchido)
SELECT id, title, deleted_at
FROM items
WHERE id = 99;
-- Encontrar todos os dados de teste para limpar após uma execução
SELECT * FROM users WHERE email LIKE '%testuser_%@test.com';Padrão 3: JOIN
Dados reais vivem em múltiplas tabelas. Um item de viagem pertence a um usuário. Um pedido pertence a um cliente e contém produtos. Você precisa de JOIN para ver o quadro completo.
-- JOIN básico: itens com o email do dono
SELECT items.id, items.title, items.status, users.email
FROM items
JOIN users ON items.user_id = users.id;
-- Filtrar o resultado do join
SELECT items.id, items.title, users.email
FROM items
JOIN users ON items.user_id = users.id
WHERE users.email = 'admin@becomeqa.com';O padrão é sempre:
SELECT [colunas que você quer]
FROM [tabela principal]
JOIN [tabela relacionada] ON [como elas se conectam]
WHERE [filtro opcional]-- Após adicionar um item como admin, verificar que está vinculado ao usuário certo
SELECT items.title, items.status, users.email AS owner
FROM items
JOIN users ON items.user_id = users.id
WHERE items.title = 'Tokyo'
ORDER BY items.created_at DESC
LIMIT 1;Padrão 4: COUNT e funções de agregação
Quando você precisa de números, não de linhas:
-- Quantos usuários existem?
SELECT COUNT(*) FROM users;
-- Quantos usuários ativos?
SELECT COUNT(*) FROM users WHERE is_active = true;
-- Quantos itens por status?
SELECT status, COUNT(*) AS total
FROM items
GROUP BY status;
-- Data de criação mais recente de item
SELECT MAX(created_at) FROM items;
-- Total de itens por usuário
SELECT user_id, COUNT(*) AS item_count
FROM items
GROUP BY user_id
ORDER BY item_count DESC;-- Após um teste de importação em massa, verificar que o número certo de registros foi criado
SELECT COUNT(*) FROM items WHERE created_at > '2026-05-15 10:00:00';
-- Verificar isolamento de dados de teste (sem contaminação entre execuções)
SELECT user_id, COUNT(*) FROM items GROUP BY user_id;Padrão 5: ORDER BY e LIMIT
Controlar quais linhas você obtém e em que ordem:
-- Itens criados mais recentemente primeiro
SELECT * FROM items ORDER BY created_at DESC;
-- Mais antigos primeiro
SELECT * FROM items ORDER BY created_at ASC;
-- Apenas os 5 mais recentes
SELECT * FROM items ORDER BY created_at DESC LIMIT 5;
-- Página 2 de resultados (linhas 11 a 20)
SELECT * FROM items ORDER BY id LIMIT 10 OFFSET 10;-- Após um teste criar um item, pegar o que acabou de ser criado
SELECT * FROM items
WHERE user_id = 42
ORDER BY created_at DESC
LIMIT 1;Juntando tudo: uma query de verificação completa
Um fluxo de teste: usuário faz login, adiciona um item de viagem chamado "Paris", marca como "Concluído". Veja como verificar a operação completa em SQL:
SELECT
items.id,
items.title,
items.status,
items.created_at,
users.email AS owner
FROM items
JOIN users ON items.user_id = users.id
WHERE items.title = 'Paris'
AND items.status = 'completed'
AND users.email = 'admin@becomeqa.com'
ORDER BY items.created_at DESC
LIMIT 1;Se retornar uma linha, o fluxo completo funcionou do início ao fim. Se não retornar nada, algo falhou silenciosamente entre o login e a atualização de status.
Usando SQL em testes Playwright
Você pode rodar SQL diretamente do código de teste usando uma biblioteca cliente de banco de dados:
import { test, expect } from '@playwright/test';
import { Client } from 'pg'; // npm install pg
test('item é salvo no banco após criação', async ({ page }) => {
// Fazer a ação na UI
await page.goto('/');
// ... login, adicionar item chamado 'Tokyo' ...
// Verificar no banco de dados
const db = new Client({ connectionString: process.env.DATABASE_URL });
await db.connect();
const result = await db.query(
'SELECT * FROM items WHERE title = $1 ORDER BY created_at DESC LIMIT 1',
['Tokyo']
);
expect(result.rows.length).toBe(1);
expect(result.rows[0].status).toBe('planned');
await db.end();
});Esse padrão é poderoso: ação de UI + verificação de banco de dados em um único teste. O teste de UI prova que a aplicação respondeu corretamente; a query de banco de dados prova que os dados foram realmente persistidos.
Erros comuns
Usar SELECT em testes de produção. Ótimo para debugging, mas nomeie colunas explicitamente em testes automatizados. Quando uma coluna é adicionada ou removida,SELECT esconde a mudança.
Esquecer o WHERE no DELETE. Se você está limpando dados de teste com DELETE FROM items WHERE email LIKE '%test%', sempre verifique o WHERE antes de rodar. DELETE FROM items sem WHERE deleta tudo.
Não usar queries parametrizadas no código. Nunca construa strings SQL concatenando input do usuário. Use placeholders $1 como mostrado acima para evitar SQL injection.
Ler dados obsoletos. Alguns bancos têm isolamento de transação que significa que você precisa fazer COMMIT antes que outra conexão possa ver as mudanças. Se seu teste escreve dados e depois os consulta de uma conexão diferente, verifique se a transação foi commitada.
O que você não precisa (ainda)
- Subqueries
- Window functions (ROW_NUMBER, RANK)
- CTEs (cláusulas WITH)
- Stored procedures e funções
- Índices de banco de dados e planejamento de queries
- Design de schema e normalização
Isso importa para desenvolvedores de banco de dados. Para QA, você lê dados. Os cinco padrões acima são o trabalho completo em 95% dos casos.
FAQ
Em qual banco de dados devo aprender SQL?PostgreSQL. É o mais comum em aplicações web modernas, tem as melhores ferramentas, e a sintaxe é padrão o suficiente para que a troca para MySQL ou SQLite leve minutos. Instale o TablePlus, conecte a qualquer instância PostgreSQL, e pratique lá.
Posso praticar SQL sem um app real?Sim. Sites como sqlfiddle.com e db-fiddle.com permitem criar tabelas e rodar queries no browser sem instalar nada. Crie uma tabela users e uma tabela items, insira algumas linhas, e pratique os cinco padrões acima.
Os dois. SQL é inestimável para debugging manual. Quando você não consegue descobrir por que um teste está falhando, verifique o banco de dados. Também é valioso em testes automatizados para verificação de dados que a UI não consegue fornecer. Comece com debugging, adicione assertions de banco de dados automatizados quando estiver confortável com as queries.
Qual a diferença entre bancos de dados SQL?Para fins de QA, quase nenhuma. PostgreSQL usa $1 para parâmetros, MySQL usa ?, mas a sintaxe de SELECT/WHERE/JOIN é idêntica. Os cinco padrões acima funcionam nos três.