VoiceOver Testing

A screenshot of the VoiceOver settings menu on iOS. Settings > Accessibility > VoiceOver

iOS Accessibility Testing with VoiceOver

VoiceOver is an assistive technology for the iOS platform which allows users to read and interact with textual expressions of the interface by using various swipe gestures and by tapping on the screen. Understanding the functionality of VoiceOver also means understanding the foundation for other assistive technologies such as Braille devices.

VoiceOver testing does not replace Voice Control, Switch, or Keyboard testing. If you haven't yet, checkout the Voice Control testing guide!

VoiceOver testing is difficult. It is important to remember that the information VoiceOver reports can be misleading. All semantic announcements can be replicated, or very closely replicated, by developers overriding combinations of an Accessibility Element's Label and Value. (See Anatomy of a VoiceOver Announcement)

Because of this, we cannot rely on a VoiceOver announcement to tell us how other users are impacted. For example, does "Double Tap to Activate" mean that the control will work in Switch Control or for a Keyboard User? What about the "Button" announcement?

Neither of these announcements are a guarantee that an element will be accessible to all assistive technologies, and in fact, it's pretty easy to accidentally create these issues when straying from using default iOS controls into the land of custom UIAccessibilityElements. This is one of the fundamental reasons we advocate for Voice Control testing in the development process! It is a very quick way to guarantee the following pieces of information:

  1. Interactivity is communicated to the OS properly.
  2. The AccessibilityLabel is accurate.

Detecting interactivity with 100% accuracy in VoiceOver is impossible. Validating the AccessibilityLabel is difficult, but there are a couple configuration tricks that can help us identify the AccessibilityLabel from the rest of the announcement.

Setting Up VoiceOver for Testing

If you are a VoiceOver user, you probably have your own VoiceOver configuration that you prefer and you may be able to hear the nuanced difference between a comma (,) and a {pause}. For those of us who don't use VoiceOver regularly, the following settings can help extract the most information for testing purposes.

  1. Caption Panel: On
    1. Where: Settings > Accessibility > VoiceOver
    2. Why: The caption panel gives you more actionable information by printing each VoiceOver announcement at the bottom of the screen.
  2. Punctuation Expansion: Commas -> Semicolons
    1. Navigate To: Settings > Accessibility > VoiceOver > Verbosity
    2. Create Punctuation Group: Testing
    3. Add Replacement: Comma -> Semicolon

This punctuation replacement is really important! When developers place too much information in the AccessibilityLabel, they will often use commas as a separator between the parts of a string. Apple likes to add commas between items (e.g. Label, Value, Hint) in the Caption Panel. By replacing "," with ";" the commas that developers have added to Label and Value become semicolons instead.

Identifying Label vs Value

Remember our "Light Switch" from the Getting Started with VoiceOver article?

  1. Accessibility Element: A switch that turns the lights on and off.
    1. Label: The Lights
    2. Trait: Switch (Private to UISwitch)
    3. Value: Off
    4. Hint: Activate to toggle.
Caption Panel: The Lights, Switch, Off, Activate to toggle

A developer could replicate the entirety of the Accessibility Announcement with the following incorrect markup.

  1. Incorrect Accessibility Element: A Light Switch... ish.
    1. Label: The Lights, Switch, Off
    2. Hint: Activate to toggle. (Hints are hard to fake!)

Notice how the developer placed information that was once in the UISwitch and the Value into the Label. This is incorrect and results in poor experience for braille users and for VoiceOver interactions with controls that have changing values. With punctuation expansion, identifying this scenario is as simple as noticing the semi-colons pop up on the caption panel we would expect the OS to print commas.

Incorrect Caption Panel: The Lights; Switch; Off, Activate to toggle.

Notice how punctuation expansion converted the incorrect commas into semi-colons, but didn't change the comma before the Hint.

The Testing Process

Now that VoiceOver is optimized for testing, let's take a look at some key elements of the testing process:

  1. Pre-req: Turn on VoiceOver
  2. For Each: Screen Change
    1. Announcements and focus transitions that occur are reasonable.
  3. For Each: Unique Screen
    1. Touch to Explore gestures can focus all Views.
    2. Rotor[Headings] skips to top level navigational landmarks.
    3. Focus Order and Information Structure is reasonable.
  4. For Each: Unique Component
    1. Accessibility announcement is concise and reasonable.
    2. Default action activates on Double Tap.
    3. Rotor[Actions] list has reasonable actions.
    4. Adjustable controls respond to Rotor[Adjustable].
  5. For Each: Layout Change
    1. New Views are announced or easily discovered.
    2. View updates are announced or expected.

Screen Change Events

Whenever a new view is loaded – whether that is a new screen, a modal dialog, or a picker – pay attention where VoiceOver focus is sent and any announcements that occur during this transition. In the majority of cases the Operating System should recognize a new view has been loaded and introspect the view to find where it should send focus (i.e. the title of the screen, the first form field on the screen, etc).

Focus does not need to go to the first element on screen after every transition. Just somewhere reasonable!

The goal here isn't to micromanage focus, but to ensure it moves to a reasonable place. If it doesn't, there might be an issue with the way the new view has been loaded such that the Operating System doesn't recognize it. In some edge cases, manually managing focus may be justified.

Explore Informative Elements by Touch

Tapping or dragging your finger around the screen, rather than swiping, is referred to as "exploring by touch." Doing this as part of the testing process allows you quickly investigate informational elements to ensure they are presented consistently, that all informative elements are focusable by touch, as well as help identify "dead zones", where there is no content for VoiceOver to focus on. Typically a dead zone isn't the sign of a blocking issue, but when apps contain a lot of dead zones, it can degrade the VoiceOver user experience and quickly limit users to swipe navigation.

Check Heading Structure with the Rotor

The Rotor determines what happens when you swipe up and down. To adjust the Rotor, put two fingers on the screen and twist clockwise or counter-clockwise, as if you were twisting a rotor. There are a few default Rotor settings – some that allow quick access to key VoiceOver settings like Speaking Rate and Language, and others that allow more dynamic navigation methods like Words, Characters, and Headings. It is good to get acquainted with the Rotor and the functionality it offers, but for the purposes of testing, checking the heading structure of each screen is critically important.


The testing process outlined above aims to simplify the nuances of VoiceOver testing and can serve as a guide for experienced accessibility testers. There's a lot more we could dive into, such as the ways information and relationships are defined in the iOS ecosystem, or various implementations of Label, Value, Trait, and Hint in common components. We'll dive into these topics in future posts :)

Featured Posts

Developing an Accessible SwiftUI Design System

Designing for Device and Text Size

Applying WCAG 2.2 to Native Mobile Applications

Creating an Efficient iOS Accessibility Test Plan