"Rodei o axe e deu zero erros, então o site é acessível." É a frase que mais engana em acessibilidade. As ferramentas automáticas são ótimas e você deveria usá-las — mas, segundo os próprios estudos das ferramentas, elas pegam algo em torno de um terço dos problemas de acessibilidade. Os outros dois terços exigem teclado, leitor de tela e julgamento humano. Entender essa divisão é o que separa "passou no scanner" de "uma pessoa cega consegue usar".
Por que acessibilidade é assunto de QA
Acessibilidade (abreviada a11y — "a", 11 letras, "y") é garantir que pessoas com deficiência — visual, motora, auditiva, cognitiva — consigam usar o produto. Além de ser o certo a fazer e de ampliar o público, é exigência legal em muitos contextos (no Brasil, a LBI; lá fora, ADA e a europeia EN 301 549). Para o QA, isso é só mais uma dimensão de qualidade: um botão que o leitor de tela não anuncia está tão quebrado quanto um que retorna erro 500 — só que o bug é invisível para quem testa olhando a tela.
WCAG e os níveis A, AA, AAA
O padrão de referência é a WCAG (Web Content Accessibility Guidelines). Ela se organiza em quatro princípios — o app precisa ser Perceptível, Operável, Compreensível e Robusto (mnemônico POUR) — e em três níveis de conformidade. O alvo prático da indústria é o AA.
| Nível | O que cobre |
|---|---|
| A | O mínimo: sem ele, grupos inteiros ficam de fora (ex.: alt em imagem, navegação por teclado) |
| AA | O alvo realista e mais cobrado legalmente (ex.: contraste 4.5:1, foco visível, rótulos de formulário) |
| AAA | O ideal, nem sempre atingível em todo conteúdo (ex.: contraste 7:1) |
A camada automática: rápida, barata e limitada
Ferramentas como axe-core (e seus wrappers: extensão axe DevTools, Lighthouse, Pa11y) varrem o DOM e pegam o que é verificável por regra: imagem sem alt, contraste insuficiente, campo de formulário sem label, ordem de cabeçalhos quebrada, atributos ARIA inválidos. É barato e deve virar parte do pipeline — um teste que falha o build quando alguém introduz uma regressão de a11y:
// axe-core dentro de um teste E2E (Playwright/Cypress)
const resultados = await new AxeBuilder({ page }).analyze()
expect(resultados.violations).toEqual([]) // falha o build se houver violação
O limite é conceitual: a máquina verifica presença, não sentido. Ela confirma que a imagem tem alt — não que o texto do alt descreve a imagem. Confirma que existe um rótulo — não que ele faz sentido. alt="imagem123.png" passa no scanner e é inútil para quem usa leitor de tela.
O que só o teste manual pega
Aqui mora a maior parte dos problemas reais — e nenhuma ferramenta substitui. Dois testes manuais dão um retorno enorme:
1. Navegação só por teclado. Guarde o mouse e percorra a página inteira com Tab, Shift+Tab, Enter e Esc. As perguntas: dá para chegar e acionar tudo? O foco está sempre visível? A ordem faz sentido? Um modal prende o foco enquanto aberto e o devolve ao fechar? Teclado quebrado é o bug de a11y mais comum e o mais fácil de achar.
2. Leitor de tela. Ligue um (NVDA no Windows, VoiceOver no Mac/iOS, TalkBack no Android) e navegue de olhos fechados. Cada elemento é anunciado com nome, função e estado? Um ícone-botão fala "botão fechar" ou só "botão"? Um erro de formulário é anunciado quando aparece? É desconfortável no começo — e é exatamente o ponto.
A pergunta que resume o teste manual não é "o atributo existe?", e sim "uma pessoa que depende disso consegue concluir a tarefa?". Essa pergunta nenhum scanner responde.
Como combinar tudo num processo
O modelo que funciona é em camadas, do mais barato ao mais caro — a mesma lógica da pirâmide de testes aplicada à a11y:
┌─────────────────────────────────────────────┐
│ Automático (axe no CI) → pega ~1/3, sempre │ barato, toda PR
├─────────────────────────────────────────────┤
│ Manual: teclado + leitor de tela │ por feature
├─────────────────────────────────────────────┤
│ Teste com usuários reais com deficiência │ o veredito final
└─────────────────────────────────────────────┘
Deixe a máquina barrar as regressões óbvias em toda PR; reserve o esforço humano (teclado e leitor de tela) para os fluxos críticos a cada feature; e, quando possível, valide com pessoas que de fato usam tecnologia assistiva — é o único teste que mede a experiência real, não a conformidade no papel.
Conclusão
Testar acessibilidade não é rodar uma ferramenta e arquivar o relatório verde. O automático (axe no pipeline) é a base barata que pega um terço dos problemas e impede regressões; o teclado e o leitor de tela pegam a maior parte do resto; e o teste com usuários reais dá o veredito. Mire em WCAG AA, trate um botão mudo para o leitor de tela como o bug que ele é, e lembre que "passou no scanner" e "é utilizável" são afirmações diferentes.
"I ran axe and got zero errors, so the site is accessible." It's the most misleading sentence in accessibility. Automated tools are great and you should use them — but according to the tools' own studies, they catch something around one third of accessibility problems. The other two thirds require a keyboard, a screen reader and human judgment. Understanding this split is what separates "passed the scanner" from "a blind person can use it".
Why accessibility is a QA topic
Accessibility (abbreviated a11y — "a", 11 letters, "y") means making sure people with disabilities — visual, motor, auditory, cognitive — can use the product. Besides being the right thing to do and widening your audience, it is a legal requirement in many contexts (in Brazil, the LBI; abroad, the ADA and the European EN 301 549). For QA, it's just one more quality dimension: a button the screen reader doesn't announce is as broken as one that returns a 500 error — except the bug is invisible to anyone testing by looking at the screen.
WCAG and levels A, AA, AAA
The reference standard is WCAG (Web Content Accessibility Guidelines). It is organized around four principles — the app must be Perceivable, Operable, Understandable and Robust (the POUR mnemonic) — and three conformance levels. The industry's practical target is AA.
| Level | What it covers |
|---|---|
| A | The minimum: without it, entire groups are left out (e.g. image alt text, keyboard navigation) |
| AA | The realistic target and the one most demanded legally (e.g. 4.5:1 contrast, visible focus, form labels) |
| AAA | The ideal, not always achievable for all content (e.g. 7:1 contrast) |
The automated layer: fast, cheap and limited
Tools like axe-core (and its wrappers: the axe DevTools extension, Lighthouse, Pa11y) scan the DOM and catch what's verifiable by rule: images without alt, insufficient contrast, form fields without a label, broken heading order, invalid ARIA attributes. It's cheap and should become part of the pipeline — a test that fails the build when someone introduces an a11y regression:
// axe-core inside an E2E test (Playwright/Cypress)
const resultados = await new AxeBuilder({ page }).analyze()
expect(resultados.violations).toEqual([]) // fails the build on any violation
The limit is conceptual: the machine checks presence, not meaning. It confirms the image has alt — not that the alt text describes the image. It confirms a label exists — not that it makes sense. alt="imagem123.png" passes the scanner and is useless to someone using a screen reader.
What only manual testing catches
This is where most real problems live — and no tool replaces it. Two manual tests give a huge return:
1. Keyboard-only navigation. Put the mouse away and go through the entire page with Tab, Shift+Tab, Enter and Esc. The questions: can you reach and trigger everything? Is the focus always visible? Does the order make sense? Does a modal trap focus while open and return it on close? A broken keyboard is the most common a11y bug and the easiest to find.
2. Screen reader. Turn one on (NVDA on Windows, VoiceOver on Mac/iOS, TalkBack on Android) and navigate with your eyes closed. Is each element announced with its name, role and state? Does an icon button say "close button" or just "button"? Is a form error announced when it appears? It's uncomfortable at first — and that's exactly the point.
The question that sums up manual testing isn't "does the attribute exist?", but "can a person who depends on this complete the task?". No scanner answers that question.
How to combine it all in a process
The model that works is layered, from cheapest to most expensive — the same logic as the test pyramid applied to a11y:
┌─────────────────────────────────────────────┐
│ Automated (axe in CI) → catches ~1/3, always │ cheap, every PR
├─────────────────────────────────────────────┤
│ Manual: keyboard + screen reader │ per feature
├─────────────────────────────────────────────┤
│ Testing with real users with disabilities │ the final verdict
└─────────────────────────────────────────────┘
Let the machine block the obvious regressions on every PR; reserve human effort (keyboard and screen reader) for critical flows on each feature; and, when possible, validate with people who actually use assistive technology — it's the only test that measures real experience, not conformance on paper.
Conclusion
Testing accessibility isn't running a tool and filing the green report. Automation (axe in the pipeline) is the cheap base that catches a third of the problems and prevents regressions; keyboard and screen reader catch most of the rest; and testing with real users gives the verdict. Aim for WCAG AA, treat a button that's mute to the screen reader as the bug it is, and remember that "passed the scanner" and "is usable" are different claims.