Node.js Protip: Avoid Global Test Runners
Some of the most popular Node.js test frameworks advertise that they should be installed globally: Jasmine, Mocha, Buster.js, etc… I consider this an anti-pattern.
am I the only one who find it “weird” that all (popular) node.js test frameworks uses a global install?
— Miller Medeiros (@millermedeiros) October 25, 2012
On this post I will try to explain why it’s an anti-pattern and show how to avoid global installs by using npm test instead.
Globals are evil!
Everybody knows that global variables are evil, but somehow nobody been talking about global installs of tools that doesn’t need to be installed globally to work. Very few Node.js modules should be installed globally, probably only tools like jshint (which can be used by text editors/IDEs) or anything that you expect to use together with other shell commands (ie. file system related tools). If your project depends on some third party code to work (including your tests) always favor local installs.
Local dependencies can be listed on the package.json file, so you keep track of the version, you can also commit them together with the project source code (making it easier for other devs to clone your project). It will reduce version conflicts and surely save you some headaches like “why do the tests work on my machine but not in others?”, which might be caused by a version conflict on the test framework.
If every single tool is installed globally the chance of name collisions will get extremely high. Please don’t do it unless you really need it.
npm test is your savior
Besides the fact of NPM being an awesome package manager it also has the very neat feature called scripts. It allows custom hooks to be executed before/after/during a certain action and comes with some good default behavior.
You probably want to run the tests multiple times and probably with the same arguments, so it’s way better to keep the test information inside the package.json file and reference the local bin file:
{
"name" : "example",
"version" : "1.0.0",
"devDependencies" : {
"jasmine-node" : "~1.0.26"
},
"scripts" : {
"test" : "node node_modules/jasmine-node/bin/jasmine-node spec"
}
}
Now you can run npm install --dev to install the devDependencies and every time you run npm test, it will execute the node node_modules/jasmine-node/bin/jasmine-node spec command, simple like that.
Automate ALL the things and avoid globals for a saner life.