Coding for Accessibility: Tools & Testing [4/6]
Hey, there!
To build truly inclusive sites and apps, accessibility needs to be integrated throughout the software development lifecycle. Rather than leaving accessibility until the end of the process, you can use tooling and automated tests during your development workflow to uncover accessibility issues. By taking proactive steps to test with a variety of tools, you can improve access with each pull request and avoid introducing technical debt.
Read on for tips on testing tools and techniques for your workflow, coming from someone who's worked on numerous accessibility tools, libraries, and JavaScript frameworks. Broaden your testing process to avoid relying on patterns and biases that can cause you to miss accessibility problems. Tooling can't uncover or fix it all, but you can still leverage computers to identify "low-hanging fruit" type-issues. Tooling can also teach you to develop for accessibility more efficiently over time.
Accessibility testing as part of your development workflow
Every day that you work on developing a User Interface (UI) is a day that you should test for accessibility. One big accessibility testing area is content and how it is structured: headings, semantic HTML, and landmarks. Accessibility testing also needs to include any user interactivity like form controls, dropdowns, layers and modals, and custom widgets. You can avoid introducing some accessibility issues in your code for these interfaces and components by using purpose-built browser extensions and automated testing to catch things as you go.
Make basic accessibility testing as habitual as saving a file by going through a short testing task list when you debug or preview a component. This could include running a browser extension like Accessibility Insights for Chrome and tabbing through pages with the keyboard. As you build and test UI features each week, test manually with NVDA for Windows and a mobile screen reader. Write automated tests for keyboard support, ARIA states, and other project-specific accessibility outcomes. Periodically, expand to more assistive technologies, platforms, and input modalities like voice control. There's a balance to achieve with the right amount of development and testing to move projects forward without leaving accessibility behind. It will take practice. It will also require human interaction and judgement calls.
People with disabilities need to be able to do things online but the majority of websites are inaccessible. You can anticipate and prevent accessibility issues from making it into a production environment with thorough testing up front. Iterating on a project is also better than never addressing it. By improving access as you go, and as issues become known to your team, you can make digital experiences better with each release (and descriptive changelog).
Automated testing provides helpful coverage for accessibility
Adding test coverage for accessibility with tools like Jest and Cypress is a great approach, whether your project has an existing test suite or not. You can automate assertions about a lot of accessibility things with code, including keyboard support and focus management, ARIA states, and accessibility API results. Tests can provide a kind of contract for how accessibility should work in your application, such as "the component closes with the escape key and returns focus to the triggering item". If someone on your team (or you, in the future) makes a change that breaks a passing accessibility test and causes it to fail, it can be identified and fixed. This is a much better way of working than accessibility issues failing in silence, requiring manual reviews to uncover.
There are some things that can't be automated, however. Screen readers haven't historically been easily automated for their output to be asserted against (hopefully soon, with tools like Assistiv Labs!). Very often, there are nuanced testing issues like quality of image alt text or audio descriptions that require human review. Tools are improving in this space daily. Yet, it's important to recognize that automation is only part of the whole process of accessibility testing. Human review is still essential for delivering good, accessible user experiences.
Common accessibility tools for a development workflow
Linters
Linters can help to catch basic accessibility issues in markup and code syntax as you work, either in a text editor/IDE or through GitHub branches and pull requests. A common linting tool for accessibility is the eslint-plugin-jsx-a11y, which ships with Create React App and other React-based frameworks, and integrates with Visual Studio Code. There is also axe Linter, a GitHub application that can analyze JSX/TSX, Vue, HTML, and Markdown formats.
Linters can help to catch basic accessibility issues in markup and code syntax as you work, either in a text editor/IDE or through GitHub branches and pull requests. A common linting tool for accessibility is the eslint-plugin-jsx-a11y, which ships with Create React App and other React-based frameworks, and integrates with Visual Studio Code. There is also axe Linter, a GitHub application that can analyze JSX/TSX, Vue, HTML, and Markdown formats.
Browser Extensions
Some of the first tools to reach for include semi-automated accessibility browser extensions: Accessibility Insights, WAVE, axe, and Lighthouse. These tools analyze rendered pages to identify violations of the Web Content Accessibility Guidelines as well as best practices with descriptive results and suggested fixes. Most of them interface with Developer Tools to make debugging easy and ergonomic, so you can test if a fix will solve an issue before making it permanent in source code.
Some of the first tools to reach for include semi-automated accessibility browser extensions: Accessibility Insights, WAVE, axe, and Lighthouse. These tools analyze rendered pages to identify violations of the Web Content Accessibility Guidelines as well as best practices with descriptive results and suggested fixes. Most of them interface with Developer Tools to make debugging easy and ergonomic, so you can test if a fix will solve an issue before making it permanent in source code.
There are also extensions for simulating the experience of a disability, such as color blindness and dyslexia: Color Contrast Analyzer, NoCoffee, ChromeLens, and Web Disability Simulator are a few. It's important to recognize that simulations are not the same as a real disabled person's experience. However, you can always learn something from running a tool to see how your pages might be perceived by someone with abilities different from your own.
Automated testing tools and APIs
For web projects, it's worth checking out Cypress for automated accessibility testing. It can effectively bolt onto any front-end stack and provide a surface for writing tests quickly. For accessibility, end-to-end tests often cover the overall experience, where components are rendered together and driven in an actual browser. You can write solid automated tests in Cypress for keyboard mechanics and interactions, in particular. Selenium Webdriver and WebDriverIO have also been helpful tools in the past.
For web projects, it's worth checking out Cypress for automated accessibility testing. It can effectively bolt onto any front-end stack and provide a surface for writing tests quickly. For accessibility, end-to-end tests often cover the overall experience, where components are rendered together and driven in an actual browser. You can write solid automated tests in Cypress for keyboard mechanics and interactions, in particular. Selenium Webdriver and WebDriverIO have also been helpful tools in the past.
Unit testing is also very helpful for component-specific accessibility behavior, custom interaction APIs like focus or layer stack managers, and text alternatives. Tools like Jest, Testing Library, Mocha, and Jasmine are very common for accessibility tests. Any component should have a range of test coverage from isolated units with no external dependencies, to end-to-end integrations with living instances of usage.
There are also accessibility test APIs that would be worthwhile to integrate in your end-to-end and unit tests, like axe-core. An accessibility test API means that you don't have to write the logic for every test yourself, a huge time saver for tricky technical things like visual contrast and ARIA requirements. You can use axe within your automated tests with cypress-axe, axe-webdriverjs, and jest-axe.
Testing on multiple platforms
It is impossible to predict how all users will navigate through your website or app, starting with their browsers and devices. Developing only in Google Chrome will leave gaps in support for other browsers, some of which are important for accessibility: Firefox and Safari in particular.
If you're developing on a Mac, set up a virtual machine (VM) environment to test on Windows. If you're developing or testing for accessibility full time, you should also consider getting a physical Windows machine to chase down pesky bugs that can't be replicated on a VM. In either case, a Windows environment will allow you to test the free and open source NVDA screen reader, which has different modes of operation than Voiceover on the Mac and is similar to JAWS–another popular screen reader. Using Parallels or similar VM software and a Windows license, you can easily test Windows browsers and assistive technologies from the comfort of your Mac computer.
Be sure to test on mobile screen readers, as well. iOS and Android devices are helpful in aiding access in the real world, so they shouldn't be forgotten. Test with iOS Voiceover and Android Accessibility to learn how they work. Play with screen magnification. And remember that people use Bluetooth keyboards with mobile devices, too! Visible focus indication is useful on mobile, in addition to desktop environments.
Click here to answer a quick question about testing tools, and I'll send the next email right away.
Until next time,
Marcy Sutton
Marcy Sutton
130 Nickerson St. Suite 207, Seattle, WA 98109