{"id":20285426,"url":"https://github.com/mramshaw/node-linting-and-testing","last_synced_at":"2026-04-12T13:04:17.779Z","repository":{"id":92905329,"uuid":"145435675","full_name":"mramshaw/Node-Linting-and-Testing","owner":"mramshaw","description":"Notes on Node Linting and Testing","archived":false,"fork":false,"pushed_at":"2020-11-13T13:34:25.000Z","size":169,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-04T03:44:36.202Z","etag":null,"topics":["bdd","chai","chai-http","cypress","doubles","eslint","github-actions","linting","mocha","mocks","node","node-js","nodejs","npm","react","reactjs","spies","stubs","tdd"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mramshaw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-20T15:26:24.000Z","updated_at":"2021-05-27T13:25:40.000Z","dependencies_parsed_at":"2023-04-13T05:00:37.855Z","dependency_job_id":null,"html_url":"https://github.com/mramshaw/Node-Linting-and-Testing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mramshaw/Node-Linting-and-Testing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FNode-Linting-and-Testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FNode-Linting-and-Testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FNode-Linting-and-Testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FNode-Linting-and-Testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mramshaw","download_url":"https://codeload.github.com/mramshaw/Node-Linting-and-Testing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mramshaw%2FNode-Linting-and-Testing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273088783,"owners_count":25043563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","chai","chai-http","cypress","doubles","eslint","github-actions","linting","mocha","mocks","node","node-js","nodejs","npm","react","reactjs","spies","stubs","tdd"],"created_at":"2024-11-14T14:26:35.345Z","updated_at":"2026-04-12T13:04:17.748Z","avatar_url":"https://github.com/mramshaw.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Node-Linting-and-Testing\n\n![node.js](/images/nodejs.png)\n\nSome notes on Linting and Testing with node.js as well as some\ngeneral thoughts on BDD \u0026 TDD frameworks.\n\n[Most of these tools may be used when developing with plain javascript\n as well as with javascript frameworks such as React or Vue.]\n\nAll of the main browsers have extensions that can verify javascript.\nWhen testing client-side javascript components, these are probably\nthe first place to start.\n\nThe notes will cover using the package manager `npm`\nbut all of this can probably be done just as easily with `yarn`.\n\n## Contents\n\n* [Type Checking](#type-checking)\n* [Linting](#linting)\n    * [Disabling eslint rules](#disabling-eslint-rules)\n* [Testing](#testing)\n    * [Testing Frameworks](#testing-frameworks)\n    * [Assertion Libraries](#assertion-libraries)\n    * [Dependency Manipulation Libraries](#dependency-manipulation-libraries)\n    * [Functional Testing Tools](#functional-testing-tools)\n        * [CircleCI](#circleci)\n        * [GitHub Actions](#github-actions)\n        * [GitLab](#gitlab)\n        * [Travis CI](#travis-ci)\n    * [HTML Parsing](#html-parsing)\n* [Code Coverage Libraries](#code-coverage-libraries)\n* [Secrets Checking](#secrets-checking)\n* [Dependency Checking](#dependency-checking)\n    * [npm audit](#npm-audit)\n    * [OWASP](#owasp)\n* [Vulnerability Scanning](#vulnerability-scanning)\n    * [GitHub](#github)\n    * [Retire.js](#retirejs)\n    * [Snyk.io](#snykio)\n* [Continuous Integration](#continuous-integration)\n* [To Do](#to-do)\n\n## Type Checking\n\nType checking adds an extra level of validation when developing in javascript.\n\n[This is the type of validation normally provided by a compiler.]\n\n* [Flow](http://flow.org)\n\nTo install:\n\n```bash\nnpm install flow-bin -D\n```\n\nUpdate `package.json` as follows:\n\n```\n  \"scripts\": {\n    \"flow\": \"flow\"\n  },\n```\n\nTo initialize:\n\n```bash\nnpm run -s flow init\n```\n\n[This will create a `.flowconfig` file, which should be committed.]\n\nTo run:\n\n```bash\nnpm run -s flow\n```\n\nNote that individual files must be annotated as follows in order to be scanned by `flow`:\n\n```javascript\n// @flow\n\n```\n\nStatus:\n\n```bash\nnpm run -s flow status\n```\n\nDetails:\n\n    http://flow.org/en/docs/\n\n## Linting\n\n* [JSLint](http://jslint.com)\n* [JSHint](http://jshint.com)\n* [ESLint](http://eslint.org)\n\nTo install:\n\n```bash\nnpm install eslint -D\n```\n\nUpdate `package.json` as follows:\n\n```\n  \"scripts\": {\n    \"eslint\": \"eslint\"\n  },\n```\n\nTo set `eslint` options (if not set globally):\n\n```bash\nnpm run -s eslint -- --init\n```\n\nTo run:\n\n```bash\nnpm run -s eslint .\n```\n\nTo run and fix errors:\n\n```bash\nnpm run -s eslint -- --fix .\n```\n\nDetails:\n\n    http://eslint.org/docs/user-guide/command-line-interface\n\n#### Disabling eslint rules\n\nIt is straightforward to disable eslint rules for specific lines of code:\n\n```node.js\n// eslint-disable-next-line no-unused-vars\nconst routes = require(\"./routes.js\")(app);\n```\n\nReference:\n\n    http://eslint.org/docs/user-guide/configuring#disabling-rules-with-inline-comments\n\n## Testing\n\n![Test Doubles](/images/Test_Doubles.png)\n\n\u003e xUnit Test Patterns: Refactoring Test Code\n\u003e by Gerard Meszaros,\n\u003e page 527\n\n#### Testing Frameworks\n\n* [AVA](http://github.com/avajs/ava)\n* [Mocha](http://mochajs.org)\n* [Jasmine](http://jasmine.github.io)\n* [Jest](http://facebook.github.io/jest)\n* [Tape](http://github.com/substack/tape)\n\nTo install:\n\n```bash\nnpm install mocha -D\n```\n\nUpdate `package.json` as follows:\n\n```\n  \"scripts\": {\n    \"test\": \"mocha\"\n  },\n```\n\nTo run:\n\n```bash\nnpm test\n```\n\n#### Assertion Libraries\n\nDepending upon your preferences for [TDD](http://www.agilealliance.org/glossary/tdd/)\nversus [BDD](http://www.agilealliance.org/glossary/bdd/), any of the following libraries\nmay be a good choice.\n\n[Note that Ava, Jasmine and Jest include their own assertion libraries.]\n\nTDD is an older and more established software practice, also hacker-friendly.\n\nBDD is a related but more formal practice, which aims to align the tests with\nthe functional specifications (which means that there need to be written\nfunctional specifications in place, perhaps more of a waterfall approach than\nan agile approach).\n\n[My take on this is that BDD and TDD are really complementary disciplines. Both take\n___best practices___ from __Design by Contract__ and __Use Cases__ (pre-conditions\nand post-conditions) and focus on putting Descartes before the horse (by writing\nthe acceptance tests before the code - and only writing code once tests fail). This\nis in contrast to what I call 'Happy Path coding' which does not take exceptions or\nerrors into consideration. My easy mnemonic for remembering which is which is 'T'\nfor technical (such as testing for exceptions, errors or edge cases) testing and 'B'\nfor business (business-related user acceptance criteria) testing.]\n\nThere are a number of BDD frameworks for languages such as Ruby (Cucumber, minitest)\nand Java (JGiven) but the focus here is on frameworks for javascript.\n\nUPDATE: It seems that Cucumber has been ported to Javascript -\n[Cucumber.js](http://www.npmjs.com/package/cucumber). There is\nat least one use of it in the wild -\n[Botium BDD Samples](http://github.com/codeforequity-at/botium-bdd-samples)\n(Botium is a testing framework for chatbots - it describes itself as\n\"The Selenium for Chatbots\").\n\n* Assert\n* [code](http://github.com/hapijs/code) is a BDD assertion library\n* [Chai](http://chaijs.com) is a BDD / TDD assertion library\n* [Should.js](http://shouldjs.github.io)\n\n[`Assert` is node's native assertion library and does not need to be installed.]\n\nTo install:\n\n```bash\nnpm install chai -D\n```\n\n#### Dependency Manipulation Libraries\n\n* [Mockery](http://github.com/mfncooper/mockery)\n* [Proxyquire](http://github.com/thlorenz/proxyquire)\n* [Rewire](http://github.com/jhnns/rewire)\n\nTo install:\n\n```bash\nnpm install proxyquire -D\n```\n\nFor more details:\n\n    http://github.com/thlorenz/proxyquire#usage\n\nIt is probably a good idea to also install Sinon:\n\n* [Sinon](http://sinonjs.org/)\n\nSinon describes itself as \"Standalone test spies, stubs and mocks for JavaScript\".\n\nIt works well with Proxyquire:\n\n    http://github.com/thlorenz/proxyquire/tree/master/examples/sinon\n\nTo install:\n\n```bash\nnpm install sinon -D\n```\n\n#### Functional Testing Tools\n\n* [PhantomJS](http://phantomjs.org)\n* [CasperJS](http://casperjs.org)\n* [Selenium WebDriver](http://www.selenium.dev/projects/#selenium-webdriver)\n* [NightwatchJS](http://nightwatchjs.org)\n* [WebdriverIO](http://webdriver.io)\n* [SuperAgent](http://visionmedia.github.io/superagent)\n* [Chai HTTP](http://chaijs.com/plugins/chai-http)\n* [Cypress](http://www.cypress.io)\n\nWe will install Chai HTTP but __Cypress__ is also worth considering\n(especially for Front-end Developers, as it can make them more Agile).\n\nCypress is a relative newcomer but shows promise. It plays well with __Mocha__ and __Chai__.\n\nCypress is JavaScript-based which makes navigating a DOM straightforward. This may\nwell obviate [HTML Parsing](#html-parsing), as described below. So, no __Cheerio__\nneeded.\n\nFor more on Cypress, check out my [Evergreen](http://github.com/mramshaw/Evergreen) repo.\n\nTo install Chai HTTP:\n\n```bash\nnpm install chai-http -D\n```\n\n#### HTML Parsing\n\nFor functional or performance testing, it is useful to be able to parse HTML responses\n(rather than `grep` for certain hard-coded text strings).\n\nEither way, determining that the HTML response is correct makes for a very brittle\nand error-prone test.\n\nFor parsing and validating HTML, Cheerio should be useful - bearing in mind that it\nwas designed for ___server-side___ HTML Parsing.\n\n* [Cheerio](http://cheerio.js.org)\n\nTo install:\n\n```bash\nnpm install cheerio -D\n```\n\n## Code Coverage Libraries\n\nOpinions differ on whether or not 100% coverage is a realistic or achievable\ngoal, however code coverage is a very useful statistic for measuring software\nquality and how it changes over time.\n\n[My opinion is that anything less than 70% code coverage is unacceptable.\n I have talked with many colleagues, and standards may change depending\n on the specific application or industry, with some sites requiring 80%\n coverage -- or even 100% coverage -- so I am NOT saying that 70% coverage\n is ideal, merely that 70% coverage is the bare minimum to start with,\n even if it results in some time lost in writing tests and/or refactoring.\n If your project is a few thousand lines of code or less, 100% coverage\n is probably the correct goal to shoot for.]\n\nIt's important to realize that 100% code coverage does NOT mean bug-free code!\n\nA downside of testing and code coverage is that it often introduces brittle\nand difficult-to-maintain tests, all of which increase the number of lines\nof code. This should never be used as an excuse ___not___ to write tests,\nbut it is something to bear in mind. For instance, it is a good idea to\nwait until any APIs have been finalized before spending too much time\nwriting tests - as any API changes will lead to multiple code changes.\n\nA balance must be maintained between writing tests and the burden of\nactually maintaining the test code, all while bearing in mind that\ntests - while valuable - do not deliver added functionality to the\nend user.\n\n* Blanket (no longer maintained)\n* JSCoverage (no longer maintained)\n* [Istanbul](http://istanbul.js.org)\n\nTo install:\n\n```bash\nnpm install nyc -D\n```\n\nUpdate `package.json` as follows:\n\n```\n  \"scripts\": {\n    \"coverage\": \"nyc --reporter=text --reporter=html mocha\"\n  },\n```\n\nTo run:\n\n```bash\nnpm run -s coverage\n```\n\n## Secrets Checking\n\nIt's quite easy for beginners or those who use IDEs or automated tools to check\nin secrets or certificates. Self-signed localhost certs are not really a concern,\nbut certificates in general are something to keep an eye on. Secrets files, if they\nabsolutely must be checked in, should be encrypted.\n\nSubmitting __pull requests__ for code review can help, also there are repo-scanning\noptions available - such as those from [GitGuardian](http://www.gitguardian.com/).\nBut a carefully constructed __.gitignore__ file is probably the first line of defence.\n\nFor private repos this is less of an issue, but for public repos it is something to\nbe guarded against. It can be a real challenge to make secrets or certificates\navailable to the CI/CD pipeline providers while keeping them secret from the\npublic. Luckily most CI/CD providers have tooling available for this purpose,\nbut it does tend to complicate the CI/CD pipeline.\n\n## Dependency Checking\n\nAny build effort should include a tool to scan dependencies for known vulnerabilities.\n\n#### npm audit\n\nProbably the first place to start is with `npm` (the node package manager) itself.\n\nFor an introduction to `npm audit`:\n\n    http://docs.npmjs.com/getting-started/running-a-security-audit\n\n\u003e `npm audit` requires packages to have `package.json` and `package-lock.json` files.\n\nTo see what vulnerabilities it can detect:\n\n```bash\n$ npm audit\n```\n\nTo see what fixes can be automatically made:\n\n```bash\n$ npm audit fix --dry-run\n```\n\nTo apply the fixes:\n\n```bash\n$ npm audit fix\n```\n\nFor a more comprehensive list of `npm audit` options:\n\n    http://docs.npmjs.com/cli/audit\n\n[It is not clear whether or not this information relies on OWASP, probably best to use both.]\n\n#### OWASP\n\nThe [Open Web Application Security Project (OWASP)](http://www.owasp.org/index.php/Main_Page)\nsponsors a number of security projects, among them a dependency checker:\n\n* [OWASP Dependency-Check](http://www.owasp.org/index.php/OWASP_Dependency_Check)\n\n[Platforms other than __Java__ and __.NET__ are supported via the Command Line tool.]\n\nThis tool ___may___ require that a Java Runtime Environment (JRE) be installed.\n\nFor more details:\n\n    http://jeremylong.github.io/DependencyCheck/general/thereport\n\nOWASP also sponsors (along with others) the [OWASP .NET Project](http://www.owasp.org/index.php/OWASP_.NET_Project)\nand the [OWASP  Node js Goat Project](http://www.owasp.org/index.php/OWASP_Node_js_Goat_Project).\n\nWhile there are no doubt many other places to search for security vulnerabilities,\nOWASP is probably as good a place as any to start.\n\n## Vulnerability Scanning\n\nAny build effort should include tools to scan for vulnerabilities.\n\n* [Burp](http://portswigger.net/burp)\n* [GitHub](#github)\n* [Retire.js](#retirejs)\n* [Snyk.io](#snykio)\n\n#### GitHub\n\n[GitHub](http://github.com) will scan your repos for vulnerabilities. They usually seem\nto be very much up-to-date. For most use cases, this is probably sufficient.\n\n#### Retire.js\n\n[Retire.js](http://retirejs.github.io/retire.js/) publishes a list of the vulnerabilities\nthat it can scan for, which is definitely worth a look.\n\nRetire.js can be integrated as a [Burp](http://portswigger.net/burp) plugin.\n\n#### Snyk.io\n\nSnyk offers reports, notifications and an attractive dashboard. It also offers a number\nof helpful integrations, such as GitHub and Travis/Jenkins. While Snyk will scan code\nwhenever code is checked-in, it will also scan code on a regular basis as well. For a\nhigher frequency of vulnerability scanning, a commercial license is recommended.\n\nSnyk publishes a list of the vulnerabilities that it can scan for:\n\n    http://snyk.io/vuln\n\nSnyk uses dependency manifests in order to determine the dependencies to scan:\n\n    http://support.snyk.io/getting-started/languages-support\n\nThis ___may___ be an issue to be aware of. For instance, note that for Golang repo\ntesting, Snyk only supports a few of the possible manifest options offered by Golang's\nmyriad dependency managers. And for Python, there will need to be a __requirements.txt__\nfile. While very useful, it's worth bearing in mind that Snyk only scans projects\nunder the control of a package manager - and uses the ___package manifest___ to do this.\nAs the manifest may not actually reflect the ___installed___ packages, this needs\nto be taken into account (this should not be a concern in a __CI__ or build pipeline).\n\nFor example, if the `requirements.txt` file contains `Flask\u003e=0.12.2` then Snyk will\nscan with the ___latest___ Flask (`flask@1.0.2` at the time of writing). This may not\nreflect the locally installed version of the particular dependency (Flask here).\n\nSnyk scans ___recursively___, which is a very nice feature indeed. This means that\nthat each package manifest will be scanned (and generate a report).\n\nSnyk also offers a CLI option, but I believe you will need a Snyk account to use it.\n\nFor more details:\n\n    http://snyk.io/docs\n\n## Continuous Integration\n\nThis is really a ___best practice___ and should include linting and code coverage tests,\nas discussed above.\n\n* [BuildBot](http://buildbot.net)\n* [Jenkins](http://jenkins.io)\n* [Strider CD](http://strider-cd.github.io)\n\nFor many uses, CIaaS (Continuous Integration as a Service) may be an attractive option.\nGitHub integration is usually relatively easy and painless, and often has a free tier.\n\n* [CircleCI](#circleci)\n* [GitHub Actions](#github-actions)\n* [GitLab](#gitlab)\n* [Travis CI](#travis-ci)\n\nMy experience has been mainly with GitHub as a source control provider, although I have\nalso used GitLab professionally. If you are on GitLab, it's a good idea to stick with\ntheir CI tools as they are pretty good. For the other options discussed below, I will\nbe considering them in terms of how well they integrate with GitHub.\n\n#### CircleCI\n\n[CircleCI](http://circleci.com) is relatively easy to use, and integrates well with GitHub.\n\nFor an example, check out my [Circling](http://github.com/mramshaw/Circling) repo.\n\n#### GitHub Actions\n\nNot surprisingly,\n[GitHub Actions](http://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions)\nintegrate well with GitHub. They are not yet the most easy to use (being still\npretty much the new kid on the block) but will probably become easier to use\neventually.\n\nFor an example with __react.js__, check out my [ReactAWS](http://github.com/mramshaw/ReactAWS) repo.\n\nFor an example with __vue.js__, check out my [VueRender](http://github.com/mramshaw/VueRender) repo.\n\n#### GitLab\n\n[GitLab](http://gitlab.com) features their own CI/CD pipelines and tools, which\noffer a pretty full slate of services.\n\nIf you are using GitLab for source control, also using GitLab for CIaaS seems like\nthe way to go.\n\nFor more on GitLab, check out my [GitLab](http://gitlab.com/mramshaw/gitlab) repo.\n\n#### Travis CI\n\nTravis CI is easy to use and integrates well with GitHub such that a code commit\ncan trigger an automated build as well as CI testing.\n\nThere are [free](http://travis-ci.org) as well as [commercial](http://travis-ci.com)\noptions.\n\nFor an example, check out my [RESTful Recipes](http://github.com/mramshaw/RESTful-Recipes) repo.\n\n## To Do\n\n- [x] Investigate [Cucumber](http://cucumber.io/) [BDD framework for Ruby] and __Gherkin__ (English-like DSL for expressing acceptance criteria)\n- [ ] Investigate [Cucumber.js](http://github.com/cucumber/cucumber-js) [BDD framework for Javascript]\n- [x] Add some notes on [Cypress](http://www.cypress.io/)\n- [x] Move Cypress notes to my [Evergreen](http://github.com/mramshaw/Evergreen) repo\n- [x] Add a note on when Snyk.io conducts vulnerability scans (on code check-in, as well as scheduled scans)\n- [x] Add a note on disabling `eslint` rules\n- [x] Add a note about GitHub Actions\n- [x] Add a note about GitHub and their vulnerability scans\n- [x] Add some notes about Secrets Checking\n- [x] Add more examples for CIaaS\n- [ ] Investigate [Serenity](http://thucydides.info/#/) [BDD framework for validating use cases]\n- [ ] Investigate [SpecFlow](http://specflow.org/) [BDD framework that describes itself as \"Cucumber for .NET\"]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmramshaw%2Fnode-linting-and-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmramshaw%2Fnode-linting-and-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmramshaw%2Fnode-linting-and-testing/lists"}