Tests are essential
- To ensure you have them, measure code coverage, for example
Instanbul nyc.
- Test quality itself takes effort to maintain over time in order for tests to continue to add value
Linting is essential
- Don't argue over syntax in Code Reviews, use tools such as ESlint with a robust configuration to prevent many potential bugs. Robust configuration means use a LOT of rules to help you write quality code. See below for list.
Grading is important
- Use a tool that measures and grades your code, e.g. js-grader Make sure grades don't drop
Standardized formatting is helpful
- Use prettier or beautifier to standardize layout, improve readability and reduce variability
- Agree on standards through tool configuration over constant code review syntax discussions
Automation of the above is essential!
The steps above MUST be incorporated into the development process as automatic procedures that make developers lives easier, not more burdensome. For example, run linting and grading before tests, run tests automatically in the cloud in CI for all code commit pushes to remote before merging them into master, run tests in master before deploying to another environment, etc. Automate code grading and consider a downgrade to be a failed test. Make quality easy and instill pride in your developers.
Tools that can run various tasks are very helpful in these efforts. For Javascript, grunt and gulp are major tools. grunt is a little more established. gulp runs faster due to using memory instead of file system. Grunt uses one config file, gulp uses multiple files with javascript code to do configuration. Using npm is almost de-facto and in 2020 npm can often be the only tool you'll need. npm example config provided at the bottom.
Example eslint.config
file that I am using:
rules:
indent:
- error
- 2
no-dupe-else-if: error
no-dupe-keys: error
no-duplicate-case: error
no-unreachable: error
prefer-const: error
eqeqeq: error
semi: error
no-var: error
no-fallthrough: error
no-new: error
no-redeclare: error
vars-on-top: error
default-param-last: error
no-mixed-spaces-and-tabs: error
no-tabs: error
no-trailing-spaces: error
no-irregular-whitespace: error
no-unused-vars: error
no-nested-ternary: error
no-multiple-empty-lines: error
no-extra-boolean-cast: warn
no-extra-parens: warn
default-case: warn
no-else-return: warn
no-eq-null: warn
no-eval: warn
no-loop-func: warn
no-native-reassign: warn
no-param-reassign: warn
no-self-compare: warn
accessor-pairs: warn
block-scoped-var: warn
no-throw-literal: warn
prefer-regex-literals: warn
camelcase: warn
no-useless-rename: warn
prefer-rest-params: warn
prefer-template: warn
Example package.json
file that I am using.
Note how scripts run linting, tests and code coverage every time.
Use
npm run coverage
to trigger all three scripts.
{
"name": "binarySearchTree",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"pretest": "eslint .",
"test": "mocha **/*.spec.* --exclude node_modules/**/*.spec.js",
"coverage": "nyc npm run test"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"chai": "^4.2.0",
"eslint": "^6.8.0",
"mocha": "^7.0.1",
"nyc": "^15.0.0"
},
"dependencies": {
"eslint-plugin-mocha": "^6.3.0"
}
}
Note the use of eslint-plugin-mocha, otherwise all the describe
s and it
s are unrecognized.