Screen readers are the primary assistive technology for blind and visually impaired users. They convert on-screen content to speech or braille output. Testing with screen readers is the most reliable way to verify your application's accessibility.
Screen Reader Market Share
| Screen Reader | Platform | Cost | Best For |
|---|---|---|---|
| NVDA | Windows | Free | Primary testing |
| JAWS | Windows | Paid | Enterprise testing |
| VoiceOver | macOS / iOS | Free | Apple device testing |
| TalkBack | Android | Free | Android testing |
| Narrator | Windows | Free | Quick Windows checks |
For thorough testing, use at least two screen readers. NVDA + VoiceOver covers the majority of users.
Getting Started with NVDA (Windows)
NVDA (NonVisual Desktop Access) is the most popular free screen reader.
Installation:
1. Download from nvaccess.org
2. Run the installer
3. Press Ctrl + Alt + N to start NVDA
Essential NVDA Commands:
┌──────────────────────────┬──────────────────────────────┐
│ Action │ Shortcut │
├──────────────────────────┼──────────────────────────────┤
│ Start/Stop NVDA │ Ctrl + Alt + N │
│ Stop speaking │ Ctrl │
│ Read next line │ Down Arrow │
│ Read previous line │ Up Arrow │
│ Read current line │ NVDA + Up Arrow │
│ Read from cursor │ NVDA + Down Arrow │
│ Navigate by heading │ H / Shift + H │
│ Navigate by link │ K / Shift + K │
│ Navigate by landmark │ D / Shift + D │
│ Navigate by form field │ F / Shift + F │
│ Navigate by button │ B / Shift + B │
│ Navigate by table │ T / Shift + T │
│ Elements list │ NVDA + F7 │
│ Toggle browse/focus mode │ NVDA + Space │
└──────────────────────────┴──────────────────────────────┘
Note: The NVDA key is Insert by default (or Caps Lock if configured).Getting Started with VoiceOver (macOS)
VoiceOver is built into every Mac.
Activation:
Press Cmd + F5 to toggle VoiceOver on/off
Essential VoiceOver Commands:
┌──────────────────────────┬──────────────────────────────┐
│ Action │ Shortcut │
├──────────────────────────┼──────────────────────────────┤
│ Toggle VoiceOver │ Cmd + F5 │
│ Read next item │ VO + Right Arrow │
│ Read previous item │ VO + Left Arrow │
│ Activate item │ VO + Space │
│ Read from cursor │ VO + A │
│ Open rotor │ VO + U │
│ Navigate by heading │ VO + Cmd + H │
│ Read current item │ VO + F3 │
│ Go to top of page │ VO + Home │
│ Interact with element │ VO + Shift + Down Arrow │
│ Stop interacting │ VO + Shift + Up Arrow │
└──────────────────────────┴──────────────────────────────┘
Note: VO (VoiceOver modifier) = Ctrl + Option by default.Screen Reader Testing Methodology
Step 1: Page Load Announcement
When a page loads, the screen reader should announce:
Expected announcements on page load:
1. Page title (from <title> element)
2. Landmark structure (header, nav, main, footer)
3. Number of headings, links, and form elements
Test: Load the page and listen to the initial announcements.
Does the page title clearly identify the content?
Step 2: Heading Navigation
Navigate through all headings to verify the document structure.
Press H repeatedly to move through headings.
Expected heading structure for a course page:
h1: "Accessibility Testing" (page title)
h2: "Course Overview" (section)
h2: "What You'll Learn" (section)
h2: "Lessons" (section)
h3: "Lesson 1: A11y Fundamentals" (lesson)
h3: "Lesson 2: WCAG Guidelines" (lesson)
h2: "Prerequisites" (section)
Problems to look for:
- Skipped heading levels (h1 -> h3, missing h2)
- Missing headings (sections without headings)
- Non-descriptive headings ("Click here", "Section 1")
- Multiple h1 elements on a single pageStep 3: Link Navigation
Press K to navigate by links.
Check each link for:
- Descriptive link text (not "click here" or "read more")
- Unique link text (two links saying "Read more" are ambiguous)
- Links that open in new windows announce it
Good link examples:
"View Accessibility Testing course"
"Download WCAG 2.2 checklist (PDF, opens in new tab)"
Bad link examples:
"Click here"
"Read more"
"Link"Step 4: Form Testing
Navigate to a form and test each field:
Tab to each form field and verify:
1. The label is announced when the field receives focus
2. Required fields are announced as "required"
3. Error messages are announced when they appear
4. Field types are announced (text, email, password, checkbox)
5. Grouped fields (radio buttons) announce the group name
Example announcement for a good email field:
"Email address, required, edit text"
Example announcement for a bad email field:
"Edit text" (no label, no required indicator)Step 5: Dynamic Content Testing
// Dynamic content must be announced to screen readers
// Use ARIA live regions for content that changes
// Method 1: aria-live attribute
<div aria-live="polite" aria-atomic="true">
{/* Content changes here will be announced */}
<p>{statusMessage}</p>
</div>
// Method 2: role="alert" for urgent messages
<div role="alert">
Form submitted successfully!
</div>
// Method 3: role="status" for non-urgent updates
<div role="status">
3 search results found
</div>
// Test by triggering the dynamic update and listening
// for the screen reader announcement
Common Screen Reader Bugs
Bug 1: Missing Form Labels
<!-- Bug: Screen reader says "edit text" with no context -->
<input type="text" placeholder="Enter your name" />
<!-- Fix: Associate a label -->
<label for="name">Full name</label>
<input type="text" id="name" placeholder="Enter your name" />
<!-- Alternative fix: aria-label -->
<input type="text" aria-label="Full name" placeholder="Enter your name" />
Bug 2: Inaccessible Custom Modals
<!-- Bug: Modal opens but screen reader continues reading background content -->
<div class="modal">
<h2>Confirm Action</h2>
<p>Are you sure?</p>
<button>Yes</button>
<button>No</button>
</div>
<!-- Fix: Trap focus and hide background -->
<div
class="modal"
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
<h2 id="modal-title">Confirm Action</h2>
<p>Are you sure you want to delete this item?</p>
<button>Yes, delete</button>
<button autofocus>No, cancel</button>
</div>
<!-- Also: set aria-hidden="true" on content behind the modal -->Bug 3: Icon Buttons Without Labels
<!-- Bug: Screen reader says "button" with no label -->
<button>
<svg viewBox="0 0 24 24"><!-- hamburger icon --></svg>
</button>
<!-- Fix: Add accessible label -->
<button aria-label="Open navigation menu">
<svg viewBox="0 0 24 24" aria-hidden="true"><!-- hamburger icon --></svg>
</button>Screen Reader Testing Report Template
Screen Reader Test Report
Application: [Name]
Screen Reader: NVDA 2024.1 / Chrome 120
Tester: [Name]
Date: 2026-03-24
Page: /courses/accessibility-testing
| # | Test Case | Result | Notes |
|----|------------------------|--------|---------------------------------|
| 1 | Page title announced | PASS | "Accessibility Testing - Academy"|
| 2 | Heading structure | FAIL | h3 used before h2 in sidebar |
| 3 | All images have alt | PASS | 4 images, all with alt text |
| 4 | Link text descriptive | FAIL | 2 "Read more" links ambiguous |
| 5 | Form labels present | PASS | Search field labeled |
| 6 | Skip nav link works | PASS | Skips to main content |
| 7 | Focus visible | FAIL | No focus indicator on cards |
| 8 | Dynamic updates | PASS | Filter results announced |
| 9 | Modal focus management | N/A | No modals on this page |
| 10 | Keyboard navigation | PASS | All elements reachable |Key Takeaways
- Screen reader testing is the gold standard for accessibility verification
- Use NVDA (free, Windows) and VoiceOver (free, macOS) for testing
- Follow a structured methodology: page load, headings, links, forms, dynamic content
- Common bugs include missing labels, broken modals, and icon-only buttons
- Document findings with specific reproduction steps and expected behavior
Next, you will learn about automated accessibility testing tools that can catch many issues before manual testing begins.