Testing an accessibility announcement in Flutter

Testing an accessibility (semantic) announcement made using SemanticsService.announce is not straight forward. This article describes how to do so.

What does SemanticsService do?

The announce method in this class is used to make a semantics announcement in cases where the system can’t. For example, if you have a countdown timer and want a semantic announcement to be made every 5 seconds. Its used in numerous places in the Flutter framework too.

To keep things simple and focus on how we test this method, we’ll make an announcement when a button is clicked. Check the sample code & the demo that follows:

Sample Code

A code sample using SemanticsService.announce

Semantics Announcement Demo

Turn on your volume to hear the announcement

Testing Semantic Announcement in Flutter

To be able to do so we’ll need some knowledge of what announce method does. Looking at the code, we see that it uses a platform channel with the channel name accessibility. It uses an object AnnounceSemanticsEvent internally to represent an announcement.

Flutter provides a way to mock platform channels in tests using TestDefaultBinaryMessenger. This class provides ways to capture and test any platform message by intercepting them and hooking into callbacks.

Check this code to see how the Flutter framework tests SemanticsService. All this code does is register a mock message handler that stores all data passed to the SystemChannel.accessibility channel into a map which is then used to assert.

This approach works well for the framework, but for us our unit tests would be depending on implementation details of the framework. Which is why is makes sense to abstract this away.

Introducing semantic_announcement_tester

Usage

  1. Create an object for MockSemanticAnnouncements in your widget test.
  2. Write the test code as usual.
  3. Use one of the matchers: hasOneAnnouncement, hasNAnnouncements or hasZeroAnnouncements to assert.

Sample Tests

https://gist.github.com/abhaysood/50f1cb296994ba66fdfd3a022325b2a9#file-main-dart-L1

To test N announcements made:

https://gist.github.com/abhaysood/50f1cb296994ba66fdfd3a022325b2a9#file-main-dart-L16

To test zero announcements made:

https://gist.github.com/abhaysood/50f1cb296994ba66fdfd3a022325b2a9#file-main-dart-L34

Happy testing!

--

--

Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store