- Notifications
You must be signed in to change notification settings - Fork153
ESLint plugin to follow best practices and anticipate common mistakes when writing tests with Testing Library
License
testing-library/eslint-plugin-testing-library
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation

ESLint plugin to follow best practices and anticipate common mistakes when writing tests with Testing Library
To use this plugin, you must haveNode.js (^18.18.0,^20.9.0, or>=21.1.0) installed.
You'll first need toinstall ESLint.
Next, installeslint-plugin-testing-library:
$ pnpm add --save-dev eslint-plugin-testing-library# or$ npm install --save-dev eslint-plugin-testing-library# or$ yarn add --dev eslint-plugin-testing-library
Note: If you installed ESLint globally (using the-g flag) then you must also installeslint-plugin-testing-library globally.
You can find detailed guides for migratingeslint-plugin-testing-library in themigration guide docs:
Addtesting-library to the plugins section of your.eslintrc.js configuration file. You can omit theeslint-plugin- prefix:
module.exports={plugins:['testing-library'],};
Then configure the rules you want to use withinrules property of your.eslintrc:
module.exports={rules:{'testing-library/await-async-queries':'error','testing-library/no-await-sync-queries':'error','testing-library/no-debugging-utils':'warn','testing-library/no-dom-import':'off',},};
With the default setup mentioned before,eslint-plugin-testing-library will be run against your whole codebase. If you want to run this plugin only against your tests files, you have the following options:
One way of restricting ESLint config by file patterns is by usingESLintoverrides.
Assuming you are using the same pattern for your test files asJest by default, the following config would runeslint-plugin-testing-library only against your test files:
// .eslintrc.jsmodule.exports={// 1) Here we have our usual config which applies to the whole project, so we don't put testing-library preset here.extends:['airbnb','plugin:prettier/recommended'],// 2) We load other plugins than eslint-plugin-testing-library globally if we want to.plugins:['react-hooks'],overrides:[{// 3) Now we enable eslint-plugin-testing-library rules or preset only for matching testing files!files:['**/__tests__/**/*.[jt]s?(x)','**/?(*.)+(spec|test).[jt]s?(x)'],extends:['plugin:testing-library/react'],},],};
Another approach for customizing ESLint config by paths is throughESLint Cascading and Hierarchy. This is useful if all your tests are placed under the same folder, so you can place there another.eslintrc where you enableeslint-plugin-testing-library for applying it only to the files under such folder, rather than enabling it on your global.eslintrc which would apply to your whole project.
Note
eslint.config.js compatible versions of configs are available prefixed withflat/, though most of the plugin documentation still currently uses.eslintrc syntax.
Refer to theESLint documentation on the new configuration file formatfor more.
This plugin exports several recommended configurations that enforce good practices for specific Testing Library packages.You can find more info about enabled rules in theSupported Rules section, under theConfigurations column.
Since each one of these configurations is aimed at a particular Testing Library package, they are not extendable between them, so you should use only one of them at once per.eslintrc file. For example, if you want to enable recommended configuration for React, you don't need to combine it somehow with DOM one:
// ❌ Don't do thismodule.exports={extends:['plugin:testing-library/dom','plugin:testing-library/react'],};
// ✅ Just do this insteadmodule.exports={extends:['plugin:testing-library/react'],};
Enforces recommended rules for DOM Testing Library.
To enable this configuration use theextends property in your.eslintrc.js config file:
module.exports={extends:['plugin:testing-library/dom'],};
To enable this configuration witheslint.config.js, usetestingLibrary.configs['flat/dom']:
consttestingLibrary=require('eslint-plugin-testing-library');module.exports=[{files:[/* glob matching your test files */],...testingLibrary.configs['flat/dom'],},];
Enforces recommended rules for Angular Testing Library.
To enable this configuration use theextends property in your.eslintrc.js config file:
module.exports={extends:['plugin:testing-library/angular'],};
To enable this configuration witheslint.config.js, usetestingLibrary.configs['flat/angular']:
consttestingLibrary=require('eslint-plugin-testing-library');module.exports=[{files:[/* glob matching your test files */],...testingLibrary.configs['flat/angular'],},];
Enforces recommended rules for React Testing Library.
To enable this configuration use theextends property in your.eslintrc.js config file:
module.exports={extends:['plugin:testing-library/react'],};
To enable this configuration witheslint.config.js, usetestingLibrary.configs['flat/react']:
consttestingLibrary=require('eslint-plugin-testing-library');module.exports=[{files:[/* glob matching your test files */],...testingLibrary.configs['flat/react'],},];
Enforces recommended rules for Vue Testing Library.
To enable this configuration use theextends property in your.eslintrc.js config file:
module.exports={extends:['plugin:testing-library/vue'],};
To enable this configuration witheslint.config.js, usetestingLibrary.configs['flat/vue']:
consttestingLibrary=require('eslint-plugin-testing-library');module.exports=[{files:[/* glob matching your test files */],...testingLibrary.configs['flat/vue'],},];
Enforces recommended rules for Svelte Testing Library.
To enable this configuration use theextends property in your.eslintrc.js config file:
module.exports={extends:['plugin:testing-library/svelte'],};
To enable this configuration witheslint.config.js, usetestingLibrary.configs['flat/svelte']:
consttestingLibrary=require('eslint-plugin-testing-library');module.exports=[{files:[/* glob matching your test files */],...testingLibrary.configs['flat/svelte'],},];
Enforces recommended rules for Marko Testing Library.
To enable this configuration use theextends property in your.eslintrc.js config file:
module.exports={extends:['plugin:testing-library/marko'],};
To enable this configuration witheslint.config.js, usetestingLibrary.configs['flat/marko']:
consttestingLibrary=require('eslint-plugin-testing-library');module.exports=[{files:[/* glob matching your test files */],...testingLibrary.configs['flat/marko'],},];
Remember that all rules from this plugin are prefixed by
"testing-library/"
💼 Configurations enabled in.
🔧 Automatically fixable by the--fix CLI option.
| Name | Description | 💼 | 🔧 | |
|---|---|---|---|---|
| await-async-events | Enforce promises from async event methods are handled | 🔧 | ||
| await-async-queries | Enforce promises from async queries to be handled | 🔧 | ||
| await-async-utils | Enforce promises from async utils to be awaited properly | 🔧 | ||
| consistent-data-testid | Ensures consistent usage ofdata-testid | |||
| no-await-sync-events | Disallow unnecessaryawait for sync events | |||
| no-await-sync-queries | Disallow unnecessaryawait for sync queries | 🔧 | ||
| no-container | Disallow the use ofcontainer methods | |||
| no-debugging-utils | Disallow the use of debugging utilities likedebug | |||
| no-dom-import | Disallow importing from DOM Testing Library | 🔧 | ||
| no-global-regexp-flag-in-query | Disallow the use of the global RegExp flag (/g) in queries | 🔧 | ||
| no-manual-cleanup | Disallow the use ofcleanup | |||
| no-node-access | Disallow direct Node access | |||
| no-promise-in-fire-event | Disallow the use of promises passed to afireEvent method | |||
| no-render-in-lifecycle | Disallow the use ofrender in testing frameworks setup functions | |||
| no-test-id-queries | Ensure nodata-testid queries are used | |||
| no-unnecessary-act | Disallow wrapping Testing Library utils or empty callbacks inact | |||
| no-wait-for-multiple-assertions | Disallow the use of multipleexpect calls insidewaitFor | 🔧 | ||
| no-wait-for-side-effects | Disallow the use of side effects inwaitFor | 🔧 | ||
| no-wait-for-snapshot | Ensures no snapshot is generated inside of awaitFor call | |||
| prefer-explicit-assert | Suggest using explicit assertions rather than standalone queries | |||
| prefer-find-by | Suggest usingfind(All)By* query instead ofwaitFor +get(All)By* to wait for elements | 🔧 | ||
| prefer-implicit-assert | Suggest using implicit assertions for getBy* & findBy* queries | |||
| prefer-presence-queries | Ensure appropriateget*/query* queries are used with their respective matchers | 🔧 | ||
| prefer-query-by-disappearance | Suggest usingqueryBy* queries when waiting for disappearance | |||
| prefer-query-matchers | Ensure the configuredget*/query* query is used with the corresponding matchers | |||
| prefer-screen-queries | Suggest usingscreen while querying | |||
| prefer-user-event | Suggest usinguserEvent overfireEvent for simulating user interactions | |||
| render-result-naming-convention | Enforce a valid naming for return value fromrender |
In v4 this plugin introduced a new feature called "Aggressive Reporting", which intends to detect Testing Library utils usages even if they don't come directly from a Testing Library package (i.e.using a custom utility file to re-export everything from Testing Library). You canread more about this feature here.
If you are looking to restricting or switching off this feature, please refer to theShared Settings section to do so.
There are some configuration options available that will be shared across all the plugin rules. This is achieved usingESLint Shared Settings. These Shared Settings are meant to be used if you need to restrict or switch off the Aggressive Reporting, which is an out of the box advanced feature to lint Testing Library usages in a simpler way for most of the users.So please before configuring any of these settings, read more aboutthe advantages ofeslint-plugin-testing-library Aggressive Reporting feature, andhow it's affected by these settings.
If you are sure about configuring the settings, these are the options available:
The name of your custom utility file from where you re-export everything from the Testing Library package, or"off" to switch related Aggressive Reporting mechanism off. Relates toAggressive Imports Reporting.
// .eslintrc.jsmodule.exports={settings:{'testing-library/utils-module':'my-custom-test-utility-file',},};
You can find more details about theutils-module setting here.
A list of function names that are valid as Testing Library custom renders, or"off" to switch related Aggressive Reporting mechanism off. Relates toAggressive Renders Reporting.
// .eslintrc.jsmodule.exports={settings:{'testing-library/custom-renders':['display','renderWithProviders'],},};
You can find more details about thecustom-renders setting here.
A list of query names/patterns that are valid as Testing Library custom queries, or"off" to switch related Aggressive Reporting mechanism off. Relates toAggressive Reporting - Queries
// .eslintrc.jsmodule.exports={settings:{'testing-library/custom-queries':['ByIcon','getByComplexText'],},};
You can find more details about thecustom-queries setting here.
Since each Shared Setting is related to one Aggressive Reporting mechanism, and they accept"off" to opt out of that mechanism, you can switch the entire feature off by doing:
// .eslintrc.jsmodule.exports={settings:{'testing-library/utils-module':'off','testing-library/custom-renders':'off','testing-library/custom-queries':'off',},};
If you find ESLint errors related toeslint-plugin-testing-library in files other than testing, this could be caused byAggressive Reporting.
You can avoid this by:
- running
eslint-plugin-testing-libraryonly against testing files - limiting the scope of Aggressive Reporting through Shared Settings
- switching Aggressive Reporting feature off
If you think the error you are getting is not related to this at all, pleasefill a new issue with as many details as possible.
If you are getting false positive ESLint errors in your testing files, this could be caused byAggressive Reporting.
You can avoid this by:
- limiting the scope of Aggressive Reporting through Shared Settings
- switching Aggressive Reporting feature off
If you think the error you are getting is not related to this at all, pleasefill a new issue with as many details as possible.
Thanks goes to these wonderful people (emoji key):
This project follows theall-contributors specification. Contributions of any kind welcome!
About
ESLint plugin to follow best practices and anticipate common mistakes when writing tests with Testing Library
Topics
Resources
License
Code of conduct
Contributing
Uh oh!
There was an error while loading.Please reload this page.