All Topics
Test Automation for Accessibility
Approaches for Testing

Approaches for Automated Testing

For any component, there are multiple types of automated tests that could apply. There’s unit testing for isolated logic and functionality, component testing for a single component or a group of components, integration testing for compound components or pages, and end-to-end testing for whole pages.

But these lines are blurry. In my opinion, you should use the automated tooling that helps you reproduce bugs and ensures fixes are baked in. What you call it is less important.

Linting

Linters are helpful for checking code before you commit it, but you might need to configure them to keep the tools helpful.

ESLint logo

You can run accessibility tests in your text editor (many of us use VS Code these days) using ESLint-Plugin-JSX-A11y (opens in a new tab).

Axe logo

There is also Axe Linter (opens in a new tab) which uses the same engine as axe-core and the Axe browser extensions.

Unit tests

Unit tests can be helpful for internal component APIs and logic. These tests shouldn’t interface with outside functions or other components.

Accessibility unit tests can assert component-specific behavior, interaction/focus APIs, the presence of text alternatives, and ARIA states.

Jest logo

Jest (opens in a new tab) is the modern standard for most unit tests in web apps these days. There are excellent tools to use with Jest for accessibility testing, including Jest DOM (opens in a new tab) with its accessibility matchers.

Testing Library logo

Testing Library (opens in a new tab) has become essential for accessibility testing with its queries and userEvent API Testing Library. It also includes framework APIs for vanilla DOM, React, React Native, Vue, Angular, Preact, Svelte, Cypress, Puppeteer, and more.

I consider these three unit testing tools (Jest, Testing Library, and Jest-DOM) to be essential for any modern web app if you can make it work with their various plugins.

Component testing

Cypress.io logo

Within automated testing, Cypress Component Testing (opens in a new tab) is also worth considering. If you already use Cypress and you like their API, you could use it to isolate single components or groups of components using the Cypress API. This is opposed to testing whole pages, to which regular Cypress is well suited.

Storybook logo

Don’t sleep on Storybook (opens in a new tab) for component testing. It bridges the gap between manual testing and automated testing, and can be essential for some teams. I’ve become a Storybook champion, now that I see how it can provide stability in the face of destructive data actions that can’t be replaced without client interaction. You can build out your components, variants, data states, and more in Storybook and test them with ease.

Integration testing

After unit testing, integration testing is the next big leap. Both integration and end-to-end testing can assert more real-world browser testing, document/page-level rules, widget interoperability, and color contrast. They also offer more flexible framework testing options.

Webdriver.io robot logoCypress.io robot logo

Integration testing is often done with Cypress (opens in a new tab) or WebdriverIO (opens in a new tab), although Jest tests can blur these lines quite a bit (as can WebdriverIO!). The goal is to bring multiple components together in test and ensure there aren’t any unexpected effects.

End-to-End testing

End-to-End testing, or e2e, covers whole pages. This allows for unique accessibility testing aspects such as page navigation and page-level issues like visual contrast or document language.

End-to-end testing isn’t necessarily distinct from integration in my experience. You also wouldn’t want to drown in testing tools just to satisfy some semantic purpose. The goal with end-to-end and integration testing is to cover the page context, and any details you can’t assert with unit tests (like link clicks actually going to a new page).

Let us appreciate these GIF metaphors. Unit tests (opens in a new tab) and Integration tests (opens in a new tab)

Configuring Testing Tools

Tool configuration can be challenging! Sometimes infrastructure changes can cause blocking issues that require a pivot: “Can these upgrades wait? Until when, and what will we do in the meantime?”

Here are some questions to ask while configuring tooling:

  • How is the UI in your app rendered? React-DOM, React-Native, Angular, etc.?
  • Can you inject tooling for accessibility tests in that context?
    • i.e., can you inject Axe into the target document or environment?
  • How is the code bundled?
    • Does it use webpack, Parcel, etc.?
    • Can you make changes to the infrastructure for accessibility testing, or will you have to make do with what’s already there? (i.e. Testing Library userEvent)
  • Who do I have to talk to to get a configuration change around here? 😏