Follow me on Twitter at @tim_deschryver | Subscribe to the Newsletter | Originally published on timdeschryver.dev.
We've all done it, committing a focused test. Most of the time this won't be spotted during a review, and this might lead to bigger problems. So... how can this be prevented?
Visual Studio Code extension
Last week, Dzhavat Ushev created the Test Focus Highlighter Visual Studio Code extension which highlights focused tests.
Neat right?! But this doesn't prevent us from committing tests, for this we have to take it a step further.
TSLint
For projects that are using TSLint, the built-in ban rule can be used to ban the usage of specific functions or global methods. I didn't know this existed, but Maxime Robert pointed me to it.
This ban rule can be configured in the tslint.json
file.
{
"rules": {
"ban": [
true,
{ "name": ["describe", "only"], "message": "don't focus tests" },
{ "name": "fdescribe", "message": "don't focus tests" },
{ "name": ["it", "only"], "message": "don't focus tests" },
{ "name": "fit", "message": "don't focus tests" },
{ "name": ["test", "only"], "message": "don't focus tests" },
{ "name": "ftest", "message": "don't focus tests" }
]
}
}
ESLint
eslint-plugin-ban
Sadly, for ESLint there isn't a built-in rule but there are options. Inspired by the TSLint ban rule, there's an ESLint ban rule that is created by the community. It has the same configuration and behaves the same way as the TSLint version.
This ban rule can be configured in the .eslintrc.json
file.
{
"rules": {
"ban/ban": [
true,
{ "name": ["describe", "only"], "message": "don't focus tests" },
{ "name": "fdescribe", "message": "don't focus tests" },
{ "name": ["it", "only"], "message": "don't focus tests" },
{ "name": "fit", "message": "don't focus tests" },
{ "name": ["test", "only"], "message": "don't focus tests" },
{ "name": "ftest", "message": "don't focus tests" }
]
}
}
eslint-plugin-jest
The second option, if you're using Jest, is to use the eslint-plugin-jest ESLint plugin. This plugin has a set of options and one of these is no-focused-tests. You can enable the rule specifically, use the "all configuration", or the "recommended configuration".
{
"extends": ["plugin:jest/recommended"]
}
Pre-commit hook
After this post was released, Netanel Basal shared a third option by using a pre-commit hook.
This will prevent a user from committing a focused test.
For this method, you have to (1) create the hook, and (2) enable the hook with for example husky.
const { execSync } = require('child_process')
const chalk = require('chalk')
/** Map of forbidden words and their match regex */
const words = {
fit: '\\s*fit\\(',
fdescribe: '\\s*fdescribe\\(',
debugger: '(debugger);?',
}
let status = 0
for (let word of Object.keys(words)) {
const matchRegex = words[word]
const gitCommand = `git diff --staged -G"${matchRegex}" --name-only`
const badFiles = execSync(gitCommand).toString()
const filesAsArray = badFiles.split('\n')
const tsFileRegex = /\.ts$/
const onlyTsFiles = filesAsArray.filter(file => tsFileRegex.test(file.trim()))
if (onlyTsFiles.length) {
status = 1
console.log(
chalk.bgRed.black.bold(`The following files contains '${word}' in them:`),
)
console.log(chalk.bgRed.black(onlyTsFiles.join('\n')))
}
}
process.exit(status)
"husky": {
"hooks": {
"pre-commit": "node hooks/pre-commit.js",
}
}
For an example, you can take a look at the Transloco library.
Thanks Netanel!
Conclusion
Using the Visual Studio Code extension helps you to spot focused tests, but doesn't prevent that these tests are committed. Using a linter helps to spot these focused tests (or skipped tests).
Linting your project during a continuous integration run will give you a warning or will throw an error (depending on how it's configured) to prevent an accidental commit.
Happy linting!
Follow me on Twitter at @tim_deschryver | Subscribe to the Newsletter | Originally published on timdeschryver.dev.
Top comments (0)