React Native accessibility testing helps mobile teams verify that translated buttons, forms, menus and notifications remain understandable through VoiceOver on iOS and TalkBack on Android. React Native provides properties such as accessibilityLabel, accessibilityRole, accessibilityState and accessibilityValue, while React Native Testing Library supports component tests that focus on user-visible behavior. Good multilingual QA checks these properties alongside the actual result of each action.
A React Native screen can show perfectly translated text while the accessible label remains English, a state is stale or an announcement interrupts the user at the wrong moment. The practical solution is to test the complete contract of each important interaction: name, role, state, action, feedback and navigation. Automated tests establish repeatable properties; real device checks establish whether those properties create a useful experience.
- Begin with meaning: identify the real action and expose an accurate translated label rather than a developer identifier.
- Check structure: verify accessibility roles, selected or disabled states, expanded sections and values where appropriate.
- Check both platforms: iOS VoiceOver and Android TalkBack can behave differently with the same React Native code.
- Check translations: include long strings, dates, plurals, complex scripts, right-to-left layouts and changing language settings.
- Check announcements: use accessibility events responsibly without constantly interrupting speech.
- Check outcomes: a successful component test is not proof of complete accessibility or perfect translation.
Why React Native needs its own accessibility test plan
React Native brings a shared component model to native mobile platforms, but it does not erase differences in how iOS and Android present accessibility information. A component’s accessible property may map to native behavior differently, and nested content may be grouped differently by VoiceOver and TalkBack. An interaction that feels clear on one platform can be noisy or difficult on the other. The test strategy should acknowledge shared code without assuming identical user experience.
A translation project adds another layer of complexity. English source text might be short and ambiguous, while the target language requires grammatical agreement, a more explicit action verb or a different word order. When the application displays one label but sets another through accessibilityLabel, reviewers may approve the visible string and miss the nonvisual experience. The source, target, native property and real task should be reviewed together.
Accessibility is a means of using the app, not merely a collection of string attributes. The most important question is whether someone can find a control, understand it, act on it and recognize the result. A test that matches the string “Save” tells little about whether the file was saved, whether a confirmation arrived or whether the button remains reachable after a modal opens. Build tests around user journeys.
The core React Native accessibility properties
The accessible property indicates that a view is exposed as an accessibility element in supported circumstances. It can also group children into a single selectable component. This is useful for a coherent button but dangerous when a container includes multiple independent actions. Review the grouping before adding properties indiscriminately to every View. Making a parent accessible can conceal the child link a person needs.
The accessibilityLabel property provides a human-readable name. It should be localized and meaningful in context. A magnifying-glass icon might need “Search messages” rather than the generic “Search” if multiple search scopes exist. The accessibilityHint can describe a result when the label alone cannot make it clear, but should not repeat information needlessly. Platform speech behavior and user settings affect whether and when hints are heard.
The accessibilityRole property communicates the kind of control, such as button, link or checkbox. The accessibilityState property can represent disabled, selected, checked, busy or expanded states. The accessibilityValue property can describe a slider or similar value-bearing component. These are not interchangeable. A checkbox called “Email alerts” needs a name and checked state; adding the word “checked” permanently to the label creates incorrect speech after the user changes it.
AccessibilityInfo and the difference between detecting and helping
React Native’s AccessibilityInfo API can query whether a screen reader is active and listen for changes in related accessibility settings. It also provides methods for posting accessible announcements. Those methods can support situations where significant dynamic information needs to be communicated, such as a completed upload or an important status change. They should be used with restraint.
Do not automatically force an announcement every time React state changes. A typing indicator updating on every character, a countdown announcing every second or a progress bar speaking every tiny increment would interrupt the person’s task. Decide what information is important, when it becomes relevant and whether native control semantics already convey it. An unnecessary announcement can be as disruptive as a missing one.
Current React Native documentation distinguishes platform-specific capabilities. Some announcement options and events behave differently on iOS and Android. Confirm the exact API available in the version the app uses rather than copying an obsolete example. A component-level mock can test that an announcement is requested with appropriate text, but only a device run can confirm its actual timing and relationship to other speech.
What React Native Testing Library is good for
React Native Testing Library encourages tests that resemble how people use components rather than tests coupled to internal implementation details. Queries based on accessible roles, labels and visible text can help establish that the user-facing control exists. Interactions can then be simulated and the resulting state verified. Test the public behavior a user depends on, not the internal name of a handler function.
Set up the test with localization providers, selected locale, application theme and known data. For a checkout button, verify the localized name and role, activate it, then assert the next screen or confirmation appears. For a checkbox, verify the unchecked state, activate it and check that the changed state is present. For a validation error, submit an invalid value, verify the error and correct the field. This style finds meaningful regressions.
A component test operates within its test environment, not a real screen-reader session. It does not necessarily capture native focus behavior, speech timing, touch-area measurements or operating-system pronunciation. An end-to-end mobile test and a manual TalkBack or VoiceOver walkthrough should complement the component test. The division of responsibility keeps the suite fast without pretending it covers more than it does.
Role-based queries versus internal identifiers
A stable test ID is useful for automation when a particular item cannot otherwise be uniquely identified, but it is not proof that a user understands the control. A test locating a button by testID may continue passing after its accessibilityLabel is accidentally removed. For accessibility checks, query by the accessible role or label where supported, and explicitly assert important state information. Then perform the action.
Be careful with selectors that depend on exact translated copy. An approved wording improvement should not necessarily break every functional test. Separate the test that protects a critical legal or safety phrase from the test that protects the button’s behavior. The first intentionally checks copy; the second can check role, presence and outcome. This makes failures actionable rather than treating every editorial improvement as an application bug.
For a repeated control such as “Open item,” the accessible name may need context: “Open invoice 1042” versus “Open invoice 1043.” Otherwise a person hears two indistinguishable actions. Tests should represent realistic lists and verify that the name disambiguates the targets without becoming absurdly long. This is a product design decision informed by language and accessibility, not simply a matcher choice.
Translate state changes and feedback separately
Static labels and dynamic messages have different jobs. A switch named “Location sharing” should remain recognizable as the setting while its checked state changes. A toast saying “Location sharing turned off” reports the outcome. Putting the full future outcome into the permanent label can make it misleading. Translate each source according to whether it names the control, describes the present state or confirms a completed action.
Think through the entire sequence: initial state, activation, confirmation if required, final state, persistence and possible error. A network-backed preference may fail to save after a tap. If the UI immediately announces success, it can mislead users when the server rejects the change. A component test should protect state consistency, while a device test confirms whether the actual spoken feedback arrives at the right point.
Error states deserve deliberate wording. “Unable to update your preference; try again” is more actionable than a generic “Error.” If a user can safely retry, expose the action. If the operation cannot be repeated, explain the alternative. A translated interface should not imply success until the application has evidence that it succeeded.
Localization across iOS and Android
The two native platforms differ in accessibility services, gestures, common navigation conventions and speech behavior. The same React Native label may be combined with different role phrases or hints. Do not include platform-generated words such as “button” inside every translated label merely to mimic one speech engine. Let the platform communicate roles where appropriate and provide the name and domain context the app controls.
Check that the app’s language selection updates visible text, accessible labels, hints and status messages together. A screen can switch to Spanish while retaining English accessibility strings because memoized props were computed under the old locale. Test both a fresh launch in the target language and an in-app change while a screen is already open. The latter is often where stale values appear.
Text expansion and visual orientation matter too. A long German label can overlap an icon; an Arabic screen can misplace punctuation around a booking identifier; a Thai paragraph can break differently from English. A JavaScript unit test can confirm resource selection, but device rendering and screen-reader exploration are necessary for the whole experience.
Scenario 1: A search icon with no useful accessible name
A messaging app uses an icon-only search button. The visual heading says “Conversations,” but TalkBack announces only a generic button. Add a localized action name to the clickable element and ensure the icon is not a second redundant focus stop. If search applies only to the current conversation, the label should distinguish that scope from searching all conversations.
Test on both Android and iOS. Open the search field, enter a term, check results and clear the query. A successful test must verify more than the icon’s existence. If the search panel opens but focus stays on the old screen, the person may not know where to type. Record a device walkthrough for focus behavior rather than trusting a component query alone.
Scenario 2: A switch says “on” after being turned off
A privacy screen displays “Share usage analytics” and a checked switch. The user turns it off, the visual control changes, but the accessibilityState still indicates checked. A language reviewer cannot fix stale data by choosing another verb. Inspect how the component state is derived and ensure the accessible state follows the same source as the setting.
Test off-to-on and on-to-off transitions, cancellation where applicable and persistence after reopening the screen. If a server request fails, the accessible state and feedback should not claim an update succeeded. Keep the label stable and the state dynamic. This makes the control understandable in every locale without duplicating platform-generated on/off phrases.
Scenario 3: A German button expands beneath the keyboard
A registration button translated into German requires two lines, pushing it into a fixed bottom region. With the keyboard open, the control is obscured. Component tests can detect some rendering assumptions, but a real phone test should confirm scrolling, safe-area behavior and touch reachability. The answer is not automatically to abbreviate a phrase that carries a necessary condition.
Test an invalid form and a valid one while the keyboard is displayed. Make sure error text does not collide with the button, and verify that a screen-reader user can reach the action through normal navigation. A visually translated screen is still unusable when its controls cannot be activated.
Scenario 4: A checkbox row swallows its terms link
A signup row contains a checkbox and a link to the terms of service. If the parent view is made accessible as one element, the link can disappear as an independent target. A screen-reader user is asked to agree without being able to inspect what they are agreeing to. Review accessibility grouping and preserve separate actions.
Test opening the terms, returning to the form, checking and unchecking consent, and submitting with the appropriate state. Separate mandatory agreement from optional marketing permission. No generic role test can decide whether those choices are ethically or legally described correctly; translation and domain review are needed.
Scenario 5: A date picker reads “14” without month or status
A reservation app displays a grid of day numbers. VoiceOver reaches a cell and says only “14,” leaving the user unsure whether it is the current month or a date outside availability. Add a useful date identity and selected or disabled state, using locale-aware formatting rather than fixed English month order. Avoid redundant verbosity that makes moving through a calendar exhausting.
Test two adjacent months, a selected date, unavailable dates and an active date range. Confirm that the resulting booking time choices become reachable and that a selected date is not communicated only through a color change. A component test can protect state; a complete device task protects the flow.
Scenario 6: An Arabic order number changes direction
A shipment screen combines Arabic text with an identifier such as ZX-5084. The number may appear or be read in an unexpected order if bidirectional handling is careless. Preserve the identifier’s exact characters and provide a copy action. Do not translate the identifier into an imagined equivalent or reverse its segments.
Test copying and pasting the code, opening the tracking link and receiving a shipping update. The accessible label should explain the code’s purpose, while the value stays stable. Device speech may handle mixed scripts differently, so native-language and screen-reader review are essential. A test that checks only string presence will miss practical confusion.
Scenario 7: A progress event interrupts every sentence
An upload screen uses AccessibilityInfo announcements for every one-percent increase. A person using a screen reader hears constant interruptions and cannot navigate to Cancel. Instead, announce meaningful milestones or final outcomes according to the task, and avoid shouting over existing speech. The platform’s native progress semantics may already supply some information.
Test a quick upload, a slow one, cancellation and failure. A final message should say what was uploaded and where the item is available. If the app reports failure, provide a recovery action and preserve the user’s work. The test should confirm that announcements are intentional and infrequent, then a real device test should check their timing.
Scenario 8: The unread badge is visual only
An Inbox tab shows a red dot, while its accessibilityLabel remains “Inbox” regardless of new messages. Communicate the unread status in a useful, localized way and keep it distinct from whether the tab is selected. If the count is displayed, plural rules may be needed. Avoid announcing private message contents in contexts where others can hear.
Test zero, one and many unread messages. When the user reads a message, both visual and accessible state should update. A simple nonempty label test cannot tell whether unread information is conveyed, so add state-based assertions and verify the spoken result on the device.
Scenario 9: A list row hides the independent save action
A video-learning app has a lesson row that opens the lesson and a bookmark icon that saves it. If the entire row is grouped as one accessible element, users cannot access bookmarking without opening the lesson. Use coherent grouping for the lesson summary but keep distinct actions discoverable. Give the bookmark an accurate selected or saved state.
Test incomplete and completed lessons, a long title and a saved item. A right-to-left layout may move the bookmark to the other side, but the action must remain independent. The component test should activate both routes separately and assert the distinct outcomes rather than merely finding the row.
Scenario 10: An error message appears without a clear field link
A form rejects an address but displays only a red “Invalid” banner at the bottom. A sighted user may guess which field is wrong; a screen-reader user cannot. Provide a specific explanation, associate it with the relevant input and make correction possible. Distinguish missing postal code, unsupported region and malformed address because the remedies differ.
Test every error trigger with stable input data. When a field is corrected, clear the old message. Do not let the submit button stay silently disabled without telling the user why. A meaningful localized error should help the person finish the task, not merely report that something went wrong.
Scenario 11: A dialogue speaks the background page first
A shipping confirmation sheet opens over a cart, but VoiceOver continues through obscured cart controls before reaching the sheet. Investigate modal containment and focus behavior on the native platform. The new task should have a clear heading, controls and dismissal action. The person should be able to complete it without interacting with invisible background content.
Test short and long translations, large text preferences and reopening the sheet after cancellation. A dialog may fit perfectly in English but require scrolling in another language. Ensure the Close and Confirm actions remain reachable and that focus returns to a sensible place afterward. A component-level tree may not reproduce all native focus behavior.
Scenario 12: A language picker uses flags rather than names
A language menu offers flags with no written language labels. This is ambiguous for languages shared across countries and inaccessible for people who cannot distinguish the symbols. Offer language names, preferably recognizable in their own scripts, and region labels when the app genuinely supports variants. Decorative flags should not become the sole spoken identity of a choice.
Test changing from English to Spanish and then to a second supported language. Verify that visible content, accessibility labels, dates and confirmation messages all update. A test that checks only the internal locale setting can pass while the screen remains partially in the previous language.
Scenario 13: A chart communicates loss only by red color
A budget chart shows a red downward trend but no navigable explanation or accessible data. A translated chart title cannot convey the amount of change or the time period. Provide a concise summary and a route to detailed values where the task requires them. Do not place fifty numbers into a single enormous label.
Test positive, negative, flat and unavailable data. The alternative wording should distinguish a loss from a planned reduction in spending, which may be a positive outcome. Colors and arrows are interpretation aids, not substitutes for precise information. A machine can check whether a label exists; an editor must confirm that it tells the right story.
Scenario 14: A disabled button has no explanation
A purchase button is disabled because the user has not chosen a shipping option. The interface does not explain this prerequisite. A screen reader may announce a disabled control, but that alone does not tell the person how to proceed. Provide a nearby instruction or error path that identifies the missing requirement. Avoid making users discover the condition by trial and error.
Test the disabled state, selecting a shipping option and then submitting. The button should become enabled and continue to the correct next step. Translate the requirement as a task instruction rather than a generic failure. A test of role and disabled state is necessary but not sufficient; the reason for the state must also be understandable.
Scenario 15: A secret code is announced in a crowded place
An authentication screen presents a one-time code field and an action to reveal entered characters. The accessible behavior must balance usability with privacy. Do not automatically announce sensitive codes to everyone nearby. Users need clear entry expectations and errors, but revealing secrets should remain an intentional choice.
Test manual entry, autofill, paste, expiration and resend. The translated copy should distinguish an incorrect code from an expired one. If a user requests another code, communicate the cooldown and outcome. A label-only test can miss both privacy and recovery problems.
Scenario 16: A custom slider has no accessible value
A podcast app has a playback-speed slider but no meaningful accessible value. It might speak only “adjustable” while the person needs to know whether playback is at 1.0 or 1.5 times. Use accessibilityValue appropriately for the supported component and keep the name separate from the changing value. Format the value in a way users can understand.
Test minimum, maximum and common presets. Verify that the actual audio engine changes speed when the control changes; a stale semantic value or decorative thumb movement is not enough. The screen-reader experience and the application’s output should agree.
Scenario 17: A support chat repeats typing updates
A chat app announces “Agent typing” on every render, interrupting the person’s message composition. Use announcement policies with restraint and distinguish transient typing status from an actual message. When a reply arrives, the user should be able to read it in the correct sequence without losing access to earlier exchanges.
Test rapid replies, delayed replies, automated responses and transfer to a human agent. Do not label a bot response as human-reviewed if that is not true. Preserve case reference numbers exactly. A technically correct localized message can still be unusable if it is announced at a disruptive time.
Scenario 18: A dark-theme warning loses contrast
A password-reset warning appears in pale orange against a light-colored dark-theme panel. The text is hard to read even though its translation is accurate. Check contrast in actual screen states and do not rely on a design screenshot created with default English text. A longer warning may wrap onto a different background area.
Also provide explicit warning wording instead of relying solely on color. A password reset can expire, fail or succeed; these are separate states. The language should say what happened and what can be done, while the visual system supports rather than replaces that meaning. Device visual review complements component assertions.
Scenario 19: A reading screen has no headings for navigation
A long educational article has bold headings visually, but the native accessible structure offers no useful section navigation. A screen-reader user must move through every paragraph. Review whether the platform and component structure expose appropriate headings, and make real sections discoverable without marking every emphasized word as a heading.
Test a short document and a long one with multiple levels, links and captions. Language changes should preserve the logical organization even when translated heading lengths differ. If the reader has a contents panel, its entries should navigate to the right section and preserve the person’s position when returning.
Scenario 20: A PDF download and preview use the same label
A file list contains two icons next to each document: one opens an in-app preview, and the other saves an offline copy. Both are labeled “Download.” A screen-reader user cannot distinguish them. Give action-specific labels and include the document title when two identical controls occur in the same list.
Test preview, download, failed download and an offline reopening. The file type and version may matter when several documents share similar titles. Translating one generic verb repeatedly will not fix a source design that confuses two real outcomes. The test should verify which action occurred.
Scenario 21: A map offers no accessible list of places
A travel app shows restaurant pins on a map. A screen reader cannot reliably use the geographic distribution alone to choose a result. Provide an equivalent list or route that includes place names, relevant characteristics and a selection action. The map remains useful visually but should not be the only path to the information.
Test filtering by cuisine, choosing a place and returning to results. Preserve official place names rather than inventing translations that would make the real location hard to identify. A label such as “Map” is not an adequate substitute for the interactive choices when the task is deciding where to go.
Scenario 22: A privacy switch uses inverted wording
A source string says “Do not share activity data,” while the switch’s enabled state actually means sharing is active. In another language the negative phrase becomes even harder to interpret. This is a product semantics failure, not merely a minor grammatical issue. Name the setting consistently with its actual behavior and display state.
Test the initial default, turning sharing on, turning it off and persistence after restart. Verify what information is affected and whether the preference takes effect immediately. A checkbox can satisfy technical role requirements while exposing a dangerously inverted choice. Human review of the wording is essential.
Scenario 23: A status message uses the wrong number form
A notification screen concatenates “3” and a translated word for “message” using English plural assumptions. In languages with additional plural categories this can produce grammatical errors or misleading meaning. Use locale-aware plural handling and keep numbers as data rather than hardcoded fragments. An accessible announcement may need a distinct, natural sentence instead of simply reading the visual badge.
Test zero, one, two, five and higher counts appropriate to supported languages. When notifications are cleared, the state should update promptly. A test should verify the actual resource selected and screen-reader presentation, while an editor confirms that agreement and word order are appropriate.
Scenario 24: An alert arrives but the app loses focus
A delivery app displays an urgent service-change alert while the user is reading an order. The app posts an announcement, then moves accessibility focus unexpectedly to the top navigation. The person hears part of the warning and loses their place. Define a priority and focus policy appropriate to the severity and whether immediate action is required.
Test a routine status update, a significant delay and a cancellation requiring rebooking. Translate these as different levels of urgency. The message should include what changed and the next action, while preserving the order reference and timing accurately. Device testing is needed because a mocked announcement call does not prove the person heard it properly.
A staged release checklist
Begin with component tests for roles, names, states, values and actions. Include a few high-value locale variations for each control pattern. Next, run complete journeys on both iOS and Android, including error recovery and language switching. Finally, review speech, text scaling, contrast, touch targets and logical reading order on representative devices. An app can pass every string test yet still block the primary action when large text overlaps the footer.
Capture evidence that another person can reproduce: device and OS, app build, locale, route, initial state, expected result, actual result and screenshots or recordings where appropriate. Assign the failure to design, code, content or translation based on evidence. The goal is not to blame the first visible string but to repair the layer that causes the misunderstanding.
Frequently asked questions
Is React Native accessibility the same on iOS and Android?
No. React Native supplies shared properties, but VoiceOver and TalkBack have platform-specific behavior, gestures and speech conventions. Verify important flows on both platforms.
Does an accessibilityLabel guarantee a good label?
No. A nonempty name can still be vague, mistranslated or misleading. A useful label should communicate the real identity or action, and it should agree with the visible interface and resulting behavior.
Should every icon receive a separate accessibility label?
No. Decorative icons may need no independent announcement when the containing control already provides the meaning. Icon-only actions need meaningful names. Avoid duplicating speech unnecessarily.
What is the purpose of accessibilityRole and accessibilityState?
The role describes the kind of element, while the state conveys properties such as disabled, selected, checked or expanded. Both support understanding alongside the accessible name.
Can AccessibilityInfo tell us whether the user has a screen reader on?
It can query screen-reader state through supported APIs and listen for changes. Those capabilities do not replace accessible component design; an app should provide useful semantics rather than wait until a screen reader is detected.
Should we announce every asynchronous update?
No. Excessive announcements disrupt navigation and speech. Communicate meaningful results at appropriate times and use native semantics where they already express the necessary information.
Can React Native Testing Library replace device testing?
No. Component tests are valuable for repeatable behavior and accessible properties. Device tests verify actual focus, touch, speech timing, rendering and platform-specific experiences.
What is the most important multilingual test?
Choose a central user task, complete it without visual reliance in the target language and confirm that the controls’ names, states and outcomes remain understandable. Add automated regression tests for the defects you discover.
What official documentation supports these methods?
Use the React Native Accessibility guide, AccessibilityInfo reference and React Native Testing Library introduction. Match APIs and query behaviors to the versions installed in your project.
Related reading
For native mobile verification, see Android TalkBack, Android Accessibility Scanner and Apple Accessibility Inspector. A technically localized app becomes genuinely multilingual when its controls, speech and outcomes preserve the meaning people depend on.