Rédaction de tests automatisés pour l'accessibilité

Marcy Sutton

By Marcy Sutton

3 janvier 2018

Un robot devant un ordinateur réfléchit à l'accessibilité

L'accessibilité du Web consiste à créer des sites et des applications accessibles à tous, en particulier aux personnes en situation de handicap. Étant donné la liste assez longue de priorités concurrentes lors du développement Web — de l'accessibilité à la performance en passant par la sécurité —, il est logique d'automatiser certaines étapes du processus. Si les tests manuels restent indispensables pour garantir l'accessibilité, une partie des efforts peut et doit être consacrée à l'automatisation, ce qui permet de libérer des ressources humaines pour des tâches plus complexes ou plus subtiles.

Les tests automatisés constituent un excellent moyen de commencer à intégrer l'accessibilité à votre site web, l'objectif final étantd'intervenirde plus en plusen amontdans le processus d'expérience utilisateur (UX) et de découverte. Les tests automatisés ne permettent certes pas de tout détecter, mais ils constituent un moyen précieux de tirer parti des améliorations faciles à mettre en œuvre et d'éviter les erreurs élémentaires. Intégrez l'accessibilité dans le code de votre interface utilisateur, documentez les fonctionnalités à l'intention des équipes et, dans l'idéal, évitez toute régression de la qualité lors du déploiement en production.

Dans cet article, nous mettrons en avant les atouts et les limites des tests automatisés en matière d'accessibilité du Web, afin d'apporter une valeur ajoutée à votre processus de travail et de soutenir les personnes en situation de handicap.

Permettre aux humains de se consacrer à des tâches plus complexes

De nombreux problèmes d'accessibilité et d'ergonomie nécessitent des tests manuels effectués par un développeur ou un responsable de l'assurance qualité, tandis que d'autres peuvent être automatisés. En fin de compte, le choix des tests automatisés que vous créerez dépendra du type de projet : s'agit-il d'une bibliothèque de modèles réutilisables ou d'un site marketing tendance ? Une bibliothèque de modèles tirerait profit d'une gamme de tests automatisés, allant des tests unitaires aux tests de régression ; un site marketing tendance aurait déjà de la chance de bénéficier de tests, quels qu'ils soient.

Pour déterminer quels tests automatiser, il est utile de se concentrer sur les éléments fondamentaux des flux utilisateur principaux. À mon avis, l’accessibilité est une exigence fondamentale de toute interface utilisateur ; alors pourquoi ne pas la prendre en compte dans la couverture de test ? Vous pouvez automatiser les tests de l’utilisabilité au clavier et des fonctionnalités des composants accessibles à l’aide de votre propre logique de test, puis y ajouter des tests supplémentaires en utilisant une API d’accessibilité pour vérifier, par exemple, le contraste des couleurs, les libellés et l’utilisation des attributs ARIA.

Voyez les choses ainsi : pouvez-vous prévoir suffisamment de temps pour tester manuellement tous les éléments de votre application ? À un certain stade, tester tout manuellement devient trop coûteux et trop chronophage, et l'automatisation devient alors une nécessité. Il s'agit avant tout de trouver le juste équilibre avec une couverture de test ciblée qui continue d'apporter de la valeur ajoutée et un bon retour sur investissement.

Unitaire, d'intégration, de bout en bout… Mais qu'est-ce que ça veut dire ?

Il existe de nombreux types de tests automatisés, mais deux domaines clés pour l’accessibilité dans le développement web sont les tests unitaires et les tests d’intégration. Ces deux sujets sont très vastes en eux-mêmes, mais l’idée de base est qu’un test unitaire couvre une partie isolée d’un système sans dépendances externes (bases de données, services ou appels réseau). Les tests d’intégration couvrent une partie plus large du système dans son ensemble, permettant ainsi de détecter d’éventuels bogues lorsque plusieurs unités sont combinées. Les tests de bout en bout constituent un type de test d’intégration, potentiellement encore plus étendu afin de reproduire l’expérience d’un utilisateur réel ; c’est pourquoi on en parle également dans le contexte de l’accessibilité.

En matière d'accessibilité, les tests unitaires couvrent généralement les API sous-jacentes qui acheminent les informations d'accessibilité ou les interactions vers la destination appropriée. Vous devez tester ces API de manière isolée, en appelant leurs méthodes avec des données factices, appelées « entrées ». Vous pouvez ensuite vérifier que ces appels de méthode modifient l'application ou son état conformément aux attentes.

it('should pass aria-label to the inner button', inject(function() {
   var template = '<custom-button label="Squishy Face"></custom-button>';
   var compiledElement = make(template);

   expect(compiledElement.find('button').attr('aria-label')).toEqual('Squishy Face');
}));

Vous pouvez effectuer des tests unitaires sur des composants d'interface utilisateur isolés pour vérifier leur accessibilité, en plus des API sous-jacentes, mais sachez que certaines fonctionnalités du DOM peuvent ne pas être fiables dans le framework de test que vous avez choisi (comme document.activeElement, ou CSS :focus). Les tests d'intégration, quant à eux, permettent de couvrir la plupart des aspects de l'accessibilité pouvant être automatisés, tels que les interactions au clavier.

Il est utile de disposer d'une gamme de tests unitaires et d'intégration pour minimiser les régressions – c'est-à-dire la mise en production de code défectueux – lorsque des modifications sont apportées au code. Pour que les tests soient utiles, ils doivent être ciblés : il ne faut pas écrire des tests juste pour le plaisir d'en écrire. Il est judicieux d'évaluer les flux utilisateur et les interactions clés, puis de vérifier leur qualité dans votre application à l'aide de tests automatisés.

Éviter les tests obsolètes

Quel que soit le type de test que vous écrivez, concentrez-vous sur le résultat, et non sur la mise en œuvre. Il arrive très facilement que des tests soient mis en commentaire ou supprimés au cours du développement s’ils échouent à chaque modification du code. Ce risque est d’autant plus grand avec les tests d’accessibilité automatisés, que vos collègues ne comprennent pas ou auxquels ils n’accordent pas autant d’importance que vous.

Pour éviter que vos tests ne deviennent obsolètes, assurez-vous que l'appel d'une méthode API produit le résultat escomptésanstester ses dépendances ni ses détails internes, susceptibles d'évoluer au fil du temps. Vous pouvez appeler les méthodes API directement dans les tests unitaires (par exemple : « avec cette entrée, la méthode renvoie X ») ou indirectement via une interaction utilisateur simulée dans les tests d'intégration (par exemple : « l'utilisateur appuie sur la touche Entrée dans le widget, et X se produit »). Tester les résultats plutôt que les implémentations facilite la refactorisation, ce qui est un avantage pour toute l'équipe !

Quel que soit le type de test que vous rédigez, concentrez-vous sur le résultat, et non sur la mise en œuvre.

En réalité, il peut être difficile de maintenir les tests d’interface utilisateur lorsque de nombreux changements de conception sont apportés – c’est souvent pour cette raison que l’on conseille d’éviter de les écrire. Mais à un moment donné, vous devriez intégrer la prise en charge de l’accessibilité afin de ne pas avoir à tout tester manuellement. En vous concentrant sur le résultat souhaité pour un composant ou une interaction particulière, vous devriez pouvoir minimiser le taux de rotation et obtenir un bon retour sur investissement pour votre suite de tests automatisés. De plus, vous éviterez ainsi que vos collègues – ou vous-même – ne compromettent la prise en charge de l’accessibilité sans vous en rendre compte.

Pour en savoir plus sur les tests, découvrez cetteprésentation de Justin Searlsqui explique comment ne plus détester vos tests.

Tests du clavier et gestion du focus

À la base, le premier outil de test d’accessibilité que je recommanderais est le clavier. Parcourez la page à l’aide de la touche Tab pour voir si vous pouvez accéder aux contrôles interactifs de l’interface utilisateur et les actionner sans utiliser la souris. Pouvez-vous voir où se trouve le curseur à l’écran ? En utilisant uniquement le clavier, pouvez-vous ouvrir une fenêtre modale par-dessus le contenu, interagir avec le contenu qu’elle contient et poursuivre facilement votre navigation après l’avoir fermée ? Il s’agit là d’interactions essentielles pour une personne qui ne peut pas utiliser de souris ou voir l’écran.

Bien que le clavier soit un outil pratique pour les tests manuels, vous pouvez également automatiser les tests de fonctionnement du clavier pour une interface utilisateur. Pour les composants interactifs tels que les sélecteurs d’onglets et les fenêtres modales, les tests permettent de s’assurer que les fonctionnalités fonctionnent à partir du clavier (et, dans de nombreux cas, avec les lecteurs d’écran). Par exemple, vous pourriez écrire des tests vérifiant que la touche Échap ferme une fenêtre modale et gère le focus, ou que les touches fléchées fonctionnent dans un menu de type bureau. Ce sont d'excellents tests à intégrer à votre application pour vous assurer qu'ils fonctionnent toujours après de nombreuses modifications du code.

L'approche des tests unitaires

On peut se demander si un test unitaire doit vérifier la position réelle du focus dans le DOM, par exemple document.activeElement ce qui est tout à fait normal. Les outils de tests unitaires échouent souvent dans cette tâche, et vous finirez par passer votre temps à traquer les bogues liés à votre infrastructure de test au lieu de rédiger des cas de test utiles.

Vous pouvez essayer d’utiliser un outil tel queSimulant, à condition que le focus clavier soit testé au sein d’une seule unité, par exemple dans un composant isolé. Dans ce cas, n’hésitez pas (et dites-moi quels outils vous aurez finalement utilisés) ! Cependant, il est souvent préférable de tester le focus clavier en environnement d’intégration, à la fois pour des raisons de facilité d’utilisation des outils et parce que le focus de l’utilisateur passe fréquemment d’un composant à l’autre (dépassant ainsi les limites d’une seule unité de code).

Au lieu de tester les interactions dans le cadre de tests unitaires et d'attendre qu'un élément soit sélectionné, vous pouvez écrire des tests unitaires qui appellent les méthodes API concernées avec des entrées statiques, telles que des variables d'état ou des fragments HTML. Vous pouvez ensuite vérifier que ces méthodes ont bien été appelées et que l'état a évolué comme prévu.

Voici un exemple de test unitaire pour l'API du gestionnaire de mise en avant issue dela bibliothèque React-Menu-button de David Clark :

it('Manager#openMenu focusing in menu', function() {
    var manager = createManagerWithMockedElements();
    manager.openMenu({ focusMenu: true });
    expect(manager.isOpen).toBe(true);
    expect(manager.menu.setState).toHaveBeenCalledTimes(1);
    expect(manager.menu.setState.mock.calls[0]).toEqual([{ isOpen: true }]);
    expect(manager.button.setState).toHaveBeenCalledTimes(1);
    expect(manager.button.setState.mock.calls[0]).toEqual([{ menuOpen: true }]);

    return new Promise(function(resolve) {
      setTimeout(function() {
        expect(manager.focusItem).toHaveBeenCalledTimes(1);
        expect(manager.focusItem.mock.calls[0]).toEqual([0]);
        resolve();
      }, 0);
    });
  });

En revanche, alors que le test unitaire ci-dessus vérifie qu'une API de gestion du focus a été appelée, un test d'intégration portant sur la gestion du focus pourrait vérifier si le focus est bien placé sur un élément DOM réel.

Voici un exemple de test d'intégration (de bout en bout) tiré du guide« howto-components » de Google :

it('should focus the next tab on [arrow right]', async function() {
   const found = await helper.pressKeyUntil(this.driver, Key.TAB,
     _ => document.activeElement.getAttribute('role') === 'tab'
   );
   expect(found).to.be.true;

   await this.driver.executeScript(_ => {
     window.firstTab = document.querySelector('[role="tablist"] > [role="tab"]:nth-of-type(1)');
     window.secondTab = document.querySelector('[role="tablist"] > [role="tab"]:nth-of-type(2)');
   });
   await this.driver.actions().sendKeys(Key.ARROW_RIGHT).perform();
   const focusedSecondTab = await this.driver.executeScript(_ =>
     window.secondTab === document.activeElement
   );
   expect(focusedSecondTab).to.be.true;
});

Pour tout élément de votre application pouvant être manipulé par survol, clic ou toucher, vous devez vous demander comment un utilisateur utilisant un clavier ou un lecteur d'écran pourrait atteindre le même objectif final. Intégrez ensuite cette réflexion dans vos tests.

Bien sûr, la combinaison de tests unitaires et d'intégration que vous choisirez dépendra en fin de compte de votre application. Mais il est toujours utile d'inclure la prise en charge du clavier dans vos tests automatisés, car cela vous permettra de savoir comment l'application doit fonctionner dans ce contexte. Ce qui nous amène à :

Tests avec l'API d'accessibilité « axe-core »

En plus des tests automatisés personnalisés de votre application, l’intégration d’une API de test d’accessibilité présente un grand intérêt. L’écriture de la logique et du code standard pour certains tests liés à l’accessibilité peut s’avérer fastidieuse et source d’erreurs ; il est donc utile de confier une partie de ce travail à des experts. Il existe plusieurs API dans ce domaine, mais ma préférée (et le projet sur lequel j’ai choisi de travailler à plein temps) est la bibliothèque d’ Deque axe-core . Elle est intégrée à Lighthouse pour Google Chrome, à Sonarwhal (développé par l’équipe Edge de Microsoft), à Ember A11y Testing, à Storybook, à Intern, à Protractor, à DAISY,et bien d’autres encore.

Il est vraiment utile de tester, à l’aide d’une API, des éléments tels que le contraste des couleurs, les tableaux de données, la conformité des attributs ARIA et les principes de base de la sémantique HTML que vous avez peut-être oubliés. L’équipe d’ axe-core se tient constamment informée de la prise en charge des différentes techniques de développement dans les technologies d’assistance, afin que vous n’ayez pas à effectuer tout ce travail vous-même ; c’est ce que nous appelons « l’accessibilité prise en charge ». Vous pouvez vous fier aux résultats des tests pour vous assurer de la prise en charge dans les navigateurs et les lecteurs d’écran que vous n’utilisez peut-être pas tous les jours, ce qui vous libère du temps pour d’autres tâches.

Vous pouvez utiliser le axe.run() Méthode API de plusieurs façons : isoler les règles d'accessibilité sur un seul composant à l'aide de la context option, par exemple dans un test unitaire. Vous pouvez également appliquer l'ensemble des règles à un document dans le cadre d'un test d'intégration au niveau de la page. Vous pouvez aussi consulter la axe-webdriverjs une intégration qui s'injecte automatiquement dans les iframes, contrairement à axe-core. Remarque : vous pouvez également utiliser les extensions de navigateur aXe pour Chrome et Firefoxpour effectuer un test manuel rapide avec le même ensemble de règles, y compris les iframes.

Voici un exemple simple d'utilisationde `axe-core ` dans un test unitaire:

var axe = require('axe-core');

describe('Some component', function() {
    it('should have no accessibility violations', function(done) {
        axe.run('.some-component', {}, function(error, results) {
            if (error) return error;
     
         expect(results.violations.length).toBe(0);
        });
    });
});

À l'inverse, voici untest d'intégration Axe-WebDriverJSqui offre une expérience davantage axée sur la page, ce qui est parfois préférable en termes de performances lorsque vous exécutez de nombreux tests :

var AxeBuilder = require('axe-webdriverjs'),
Webdriver = require('selenium-webdriver');

describe('Some page', function() {
  it('should have no accessibility violations', function(done) {
    var driver = new Webdriver.Builder().forBrowser('chrome').build();

    driver.get('http://localhost:3333')
      .then(function(done) {
        AxeBuilder(driver)
          .analyze(function(results) {
            expect(results.violations.length).toBe(0);
            done();
        });
    });
  });
});

Dans ces deux tests, un objet JSON vous est renvoyé contenant toutes les informations détectées par axe-core : des tableaux de validations, d’infractions, et même un ensemble d’éléments « incomplets » nécessitant une vérification manuelle. Vous pouvez écrire des assertions basées sur le nombre d’infractions, ce qui s’avère utile pour bloquer les builds localement ou dans le cadre de l’intégration continue (CI).

Il est important de créer plusieurs tests pour chaque état de la page, y compris l'ouverture des fenêtres modales, des menus et d'autres zones masquées qui, sinon, seraient ignorées par l'API. Cela permet de s'assurer que vous testez l'accessibilité de chaque état de la page, car un outil automatisé ne peut pas deviner votre intention lorsque des éléments sont masqués par display: none ou injecté dynamiquement à l'ouverture.

Vous pouvez consulter la axe-core documentation de l’API aXe etaxe-webdriverjspour découvrir toutes les options de configuration, qu’il s’agisse de désactiver des règles spécifiques, d’inclure ou d’exclure certaines parties du DOM, ou encore d’ajouter vos propres règles personnalisées. Lafuture version 3.0 d’ axe-coreprend également en charge le Shadow DOM, que vous pouvez utiliser avec une version préliminaire de l’API ou dansl’extension gratuiteaXe Coconut.

Découvrez d'autres intégrations et ressources sur le site web de l'axe-core :https://axe-core.org

Tests manuels et tests utilisateurs

Il est important de rappeler que les tests automatisés ont leurs limites en matière d'accessibilité. Ils ne peuvent en aucun cas se substituer aux tests manuels effectués à l'aide du clavier et de lecteurs d'écran, y compris sur les appareils mobiles. Certains de ces scénarios ne peuvent d'ailleurs pas être automatisés du tout.

Les tests manuels et vos tests automatisés vous permettent de couvrir les aspects fondamentaux. Mais pour déterminer si votre application est réellement utilisable par des utilisateurs, il faut recourir à des tests utilisateurs. Ce n’est pas un hasard si des initiatives récentes telles que l’ACAA (Air Carrier Access Act) exigent la réalisation de tests utilisateurs dans le cadre de leurs mesures correctives.

Une fois que votre expérience numérique s'est quelque peu stabilisée, il est extrêmement important de procéder à des tests utilisateurs avec de vraies personnes, y compris celles en situation de handicap. La phase de prototypage peut toutefois constituer une exception à cette règle, car c'est à ce stade que vous souhaitez recueillir les retours des utilisateurs avant de choisir une solution définitive. Dans tous les cas, des organismes telsqu'Access Workspeuvent vous aider à trouver des utilisateurs pour vos tests. Vous devriez également envisagerde réaliser des tests à distanceafin de tirer le meilleur parti de vos efforts.

Pour conclure

Les tests automatisés peuvent permettre à votre équipe de ne plus avoir à tester manuellement chaque élément de votre application ou de votre site web. À partir d’un certain stade, les tests automatisés s’avèrent plus efficaces que le recours à des intervenants humains pour toutes ces tâches. En élaborant une stratégie de test réfléchie et en y intégrant des tests d’accessibilité, vous pouvez communiquer la qualité du code aux membres de votre équipe et, potentiellement, éviter que des régressions ne soient déployées en production.

Des tests automatisés efficaces vérifient les interactions au clavier, l'infrastructure des API accessibles et l'utilisation d'API de test d'accessibilité telles que axe-core , ce qui vous évite d'avoir à écrire du code standardisé, source d'erreurs. Cependant, les tests automatisés ne remplacent pas les tests manuels réguliers que vous effectuez vous-même, ni les testsréalisés avec de vrais utilisateurs. Une approche de test globale et équilibrée constitue le meilleur moyen de garantir le maintien de la qualité à toutes les étapes du processus.

N'hésitez pas à me contactersur Twittersi vous avez des questions ou si vous avez une autre approche ! Je serais ravi de savoir ce qui fonctionne pour vous.

Comme aime à le dire ma collègue Glenda Sims : « Vers l'accessibilité et au-delà ! »

Marcy Sutton

Marcy Sutton

Marcy est « Developer Advocate » chez Deque Systems. Elle fait également partie de l'équipe #axeCore, organise les rencontres @a11ySea et est passionnée de montagne.

Recevez les articles de blog directement dans votre boîte mail

Pas de bavardages inutiles, mais des informations concrètes sur l'accessibilité, fournies par des experts qualifiés.

Vous acceptez que Deque , utilise et partage des informations conformément à Dequedéclaration de confidentialité. Vous pouvez modifier votre consentement à tout moment en nous contactant.

En savoir plus sur ce sujet

Test your custom elements and trust the results with Axe-core’s support for ElementInternals

Wilco Fiers 400 x 400 1 300 x 300
August 27, 2026 By Wilco Fiers

If you're a large enterprise organization with accessibility issues resulting from interoperability challenges, moving to ElementInternals is a savvy move. You can standardize, and safely test. And, with Axe-core now supporting ElementInternals, you can test those components and trust the results.

Lire l'article
A testing flow, depicting a single custom button scanned by Axe-core for React, Angular or Vue frameworks

Deque and Microsoft: Two decades of shaping the future of accessibility

cropped preety kumar400x400 300x300 1 1.jpg
August 25, 2026 By Preety Kumar

What started nearly two decades ago as conversations between two people passionate about improving accessibility across Microsoft's digital experiences has grown into a lasting partnership built on shared learning, mutual respect, and a common belief that accessibility should be built into every stage of software development.

Lire l'article
Preety Kumar and Jenny Lay-Flurrie conducting an interview, with the Seattle skyline in the background.