Accessibility testing

Posted 7 September 2023


Accessibility of web applications has become something companies can no longer ignore. The moral responsibility of practicing inclusivity combined with the legal threat from accessibility laws means that understanding how to build and test for accessibility is vital knowledge for any frontend developer.

The Web Content Accessibility Guidelines (WCAG) lay out the standards for ensuring a website can be used by anyone no matter their impairments. Most legislation targets level AA compliance, which doesn't happen without a conscious effort to understand these standards and validate they are being met.

Considering accessibility can be integrated throughout your development process:

  • Approach: The way you plan and develop
  • Automation: Integrating checks into your automated tests
  • Manual testing: Auditing your applications
  • Beyond engineering: Facing issues beyond the code

Approach

Thinking about accessibility

The first step is to start thinking about accessibility. Become a champion for accessibility concerns by reading the WCAG documentation to understand some of the common accessibility issues many web pages suffer from. When you start to scratch the surface you'll quickly discover how many issues there are that you may have been lucky enough to never have to consider.

The goal is to ensure that accessibility is being considered at the earliest point possible. Raise accessibility concerns in planning and refinement meetings and make sure accessibility is incorporated in your approach from the start. Push back on changes that will make accessibility for all worse and add to accessibility debt. It's not enough to rely solely on automated testing to detect problems.

Re-use solutions

Using public or internal libraries can be a great way to avoid having to re-invent the wheel and solve common accessibility problems from scratch. Using a component framework such as MUI or Chakra can provide common components with accessibility concerns built in. Sharing your own internal components through a design system library can also help share these accessibility best practices, allowing you to solve accessibility concerns once and share solutions across teams.

Use native browser elements whenever you can as these are implemented to be accessible for a wide range of use cases. Do you really need to build a custom <select> or <input type="date" />?

If you have to build your own custom components, react-aria provides a set of React hooks to provide accessibility and behaviour to most common components.

Storybook

Storybook is a great tool for developing, documenting and testing frontend components in isolation. It also has a few useful tools for accessibility testing.

With the accessibility addon each story will be scanned with axe and any detected issues shown in a panel. This can help provide quick feedback on potential accessibility issues while developing components.

The addon also provides a range of colour filters you can apply to simulate what your UI looks like to users with a range of colour blindness types. You can use this to easily test that the UI is still usable for any users with colour blindness.

Automation

Use accessibility linting rules

Static analysis can catch some accessibility problems. Extending your eslint config with something like eslint-plugin-jsx-a11y will detect issues like missing alt attributes on img tags and invalid aria attributes.

This can provide instant feedback in your IDE as you're writing JSX.

Write unit tests with Testing Library

Testing library encourages developers to write less brittle tests that are more resilient to refactoring. Queries that find elements on the page in the same way a user would rather than with XPath-like selectors are more resilient to breaking from design changes or refactoring. For example, finding a password field by querying for an input element with the label Password will continue to work even if the design of the page is overhauled, compared to querying for an element with a .password-input class name.

This approach also has the benefit of encouraging more accessible components. Labels and aria attributes make it easier for you to write resilient tests that query for elements based on semantic tags while at the same time make it easier for users with screen readers to find those same elements. If you're struggling to write a query using testing-library's built in selectors it's probably because your UI is not following accessibility standards.

Testing-library has integrations with a range of frameworks including React, Angular, Svelte and plain DOM.

Use axe with unit and integration tests

axe is a powerful tool for automated accessibility testing of web pages. It can be used to scan a page for accessibility issues and has integrations with a range of other testing tools you may already be using as part of your automated testing pipeline.

You can use axe with automated browser testing tools like Playwright and Puppeteer. By testing each page of your application you can catch accessibility problems before they are released to users. If you're adding this to an existing project you can also use snapshot testing to define a baseline of current accessibility problems to ensure you aren't making things worse as you add new features.

With jest-axe you can add unit tests that use axe to detect accessibility issues in a JSDOM environment. This can be useful for getting earlier feedback rather than waiting for the results of a full integration test.

Manual testing

Using automated testing tools like axe can only catch ~60% of accessibility issues on average. For example, an automated tool can detect the presence of an alt attribute on an <img /> element but can't tell whether the text is actually a meaningful description of the image. For this reason manual testing should also be included in your accessibility approach.

Documents like VPAT can be used to guide your manual testing and can be shared with external users to demonstrate the compliance of your application to accessibility standards. Having a regular cadence to manually assess and review accessibility can help discover issues and track accessibility over time, as well as reassuring your users that you are prioritising accessibility.

Having real users with impairments test your website is the best way to discover how truly accessible your system is. Try to use your website with a screen reader or without a mouse to get an idea of how usable it really is.

Beyond engineering

Engineering best practices alone can't solve all accessibility problems - your whole organisation has a role to play.

Designers need to consider accessibility from the initial UX and UI designs. Tools like Figma have accessibility integrations that can help ensure design mocks are created with accessibility in mind.

Anyone who produces web content needs to be aware of accessibility and its importance. Your CMS may require providing alt text for images but does everyone understand the importance of this field and how to write usable captions for those using screen readers? Does all video content produced include captions?

Using approaches like Employee Resource Groups (ERGs) or cross-functional working groups can help organise and promote the importance of accessibility across the organisation. From office provisions to internal systems to external web applications accessibility needs to be considered and a culture of prioritising these requirements needs champions to promote it.


Related posts

Design system management

Published

Processes and challenges in managing an adopted design system

Exclude node_modules with Webpack

Published

Avoid bundling dependencies when building a library

Contract testing with OpenAPI & TypeScript

Published

Validate contracts between backend services and frontend applications


Thanks for reading

I'm Alex O'Callaghan and this is my personal website where I write about software development and do my best to learn in public. I currently work at Mintel as a Principal Engineer working primarily with React, TypeScript & Python.

I've been leading one of our platform teams, first as an Engineering Manager and now as a Principal Engineer, maintaining a collection of shared libraries, services and a micro-frontend architecture.