I have a several tests for node js express application written in coffeescript run under Mocha control.
Unfortunately mocha runs all my tests twice, becouse in the same directory I jave .coffee and .js files. The .js files are generated by my editor automatically together with .map files. That's quite handy if I need to debug something.
How can I filter that only .coffee or .js are executed from directory not both of them?
In your package.json, create entries like the following:
"scripts": {
"test": "npm run test-coffee",
"test-js": "mocha -R spec test/*.js",
"test-coffee": "mocha -R spec test/*.coffee"
}
Now you can run npm test, npm run test-js, or npm run test-coffee. If you have tests in subdirectories, you will want to use the find command to run just the subtests you're interested in.
Mocha by default runs files with pattern: test/*.{js,coffee} which includes both coffee and js files. In your case, it will find both coffee and js files of each test, thus your tests are run twice.
You may want to set the file pattern explicitly, something like:
mocha -R spec "test/*.js"
If you have tests in subdirectories, you can use globstar (**) in your pattern like this:
mocha -R spec "test/**/*.js"
Note the use of double quotes. If you omit double quotes they will be interpreted by shell and it may not be able to match files in subdirectories. Using double quotes passes the pattern to mocha, and mocha handles it correctly.
Related
I added the type: module but that didn't help.
I am trying to run mocha or jest tests that use import and export for the source files.
The existing questions about this have specifics that are different from mine and I also find them confusing to follow for someone with my specific situation, especially since I have developed a specific answer with details not relevant to the existing questions, but relevant to other people in my situation.
In the past, you could not use ES modules (i.e. import/export) in Node without transpiling your code using Babel. However, support for ES modules in Node is now a reality, and both Jest and Mocha have also recently added support for using ES modules natively.
It takes more than just adding "type": "module" to your package.json, however.
Steps for using native ES Modules in Jest
As already mentioned, add "type": "module" to your package.json
Install either jest-environment-node or jest-environment-jsdom-sixteen to your development dependencies. For example:
$ npm i -D jest-environment-node
Update the Jest configuration in package.json and add the testEnvironment setting. For example:
"jest": {
"testEnvironment": "jest-environment-jsdom-node"
}
If you are using a version of Node earlier than 13.2, then you will need to add two additional flags when running Node: --experimental-modules and experimental-vm-modules. I use npx to execute the commands, although it's a little verbose:
$ npx --node-arg=--experimental-modules --node-arg=--experimental-vm-modules jest
This will run all your Jest tests using the appropriate Node flags. I'd recommend making this your test script in package.json if this is the way you go.
Now you should be able to use import/export without Babel!
One last important point: when using native ES modules in Node, you have to use the entire import path to your local modules, including the file extensions. For example:
import lib from "./my/lib.js"
Here is the Node documentation on native ES modules, if you want to read about this in more detail: https://nodejs.org/dist/latest-v14.x/docs/api/esm.html
I'd also recommend reading through this Github issue for more details on the Jest implementation of native ES modules: https://github.com/facebook/jest/issues/9430
Per the Jest documentation, if you make sure babel-jest is installed and supply your Babel configuration per the Babel documentation, in a config file or package.json e.g.:
.babelrc.json
{
"presets": [
"#babel/env"
]
}
Then babel-jest will pick it up automatically and you don't need to explicitly pre-build the files to test them. This also means you don't have to set flags on the command line when calling Babel.
Note that if you do want to explicitly pre-build, I'd recommend:
Using a pre<script> script rather than having multiple steps in one line; and
Re-using the build script so you don't have to make changes in two places.
In your case:
"scripts": {
"build": "babel src/ --out-dir lib",
"pretest": "npm run build",
"test": "jest lib/*.test.js"
}
You need to use a compiler and then use the compiled files when running tests.
Many of the references say to add type: module but don't say much more.
To be clear, the basic message:
SyntaxError: Cannot use import statement outside a module
is because you are using import/export and you are trying to run the files directly without compilation.
The mindshift here is getting used to editing the files in one directory and running the tests in another. Alternatively, some solutions offer "in'flight" compilation so this detail is essentially hidden and only the source files are used.
There are a few different approaches to doing this depending on specific needs. Here is one of the simplest approach I've found so far, using Babel for the compilation step:
Install babel npm install babel --save-dev
Add babel commands in package.json scripts, for example:
"scripts": {
"test": "babel src/ --out-dir lib --presets=#babel/env; jest lib/*.test.js",
"build": "babel src/ --out-dir lib --presets=#babel/env"
}, // this was for jest but you can use mocha, etc as needed
// Note that using preset this way eliminates the need for a specific .babel.config.json file
Now, if you run:
jest .
you get SyntaxError: Cannot use import statement outside a module, but if you run npm t you get
Successfully compiled 2 files with Babel.
PASS lib/app.test.js
All tests
✓ Canary test (2ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Going forward, just remember to:
Edit files in src/
Run tests in lib/
I am amassing a list of test files which need to be run. I'd like to pass them into Mocha via the command line. My current command looks like this:
{here}/node_modules/mocha/bin/_mocha -u tdd --timeout 999999 --colors --file {here}/tests/core/core_tests.js -R json > {here}/rpt.json
The spec for mocha says I should be able to repeat that --file pattern infinitely to load multiple files, but when I do this with even one I get this error:
Warning: Cannot find any files matching pattern "test"
This core_tests.js file, when run directly without the --file option, runs just fine.
What am I missing? How do I pass multiple files without doing it by directory?
One of my co-workers added this Ava package to our setup, and it's done something I've never seen a Node package do before: interfere with other packages! Now when I try to run Mocha I get:
$ node_modules/mocha/bin/mocha test/
Test files must be run with the AVA CLI:
$ ava node_modules/mocha/bin/_mocha
I get that Ava would like to run my Mocha tests, but if I wanted that I'd run ava mocha not mocha. And because a co-worker is using it I can't simply uninstall the package.
Is there any way I can run plain Mocha tests on a machine with Ava installed?
One of the files in test/ imports ava and the imported code will recognise that it's not being run with the correct tooling and throw an error.
Might be worth subdividing your test/ directory to keep tests associated with their respective runners.
test/
ava/
SomeAvaTests.js
mocha/
SomeMochaTests.js
This way you can safely run mocha test/mocha/ and vice versa without worrying about treading on each other's toes.
I cant get my head around how scripts are running within package.json & would appreciate some insight for us newbies.
Is it the case that they are bash scripts that are run by node having loaded the various dependencies?
If yes, then how does it process the javascript code?
Is it the case that they are bash scripts
yes
that are run by node
no, they are run by sh.
having loaded the various dependencies?
no, no js files are loaded, the only thing npm does for you is to prepare the environment. Among other things, it adds ./node_modules/.bin to PATH so you can invoke installed modules immediately.
When you run npm run-script whatever, this is what npm does:
reads the corresponding command line from package.json
prepares the environment
invokes sh (or comspec on win) and gives it the command and the env. No big magic here.
This may not be 100% accurate so I implore other, more qualifies, experts to chime in.
NPM is a program, installed as part of the Node.JS environment. It's two main uses (as describe here) are for searching for node.js packages and installing node.js packages.
However, NPM is also capable of understanding "simple" (a relative term) scripts.
When you write a script in your package.json, and issue the NPM command, say "npm start", NPM will read and interpret the script. NPM then searches your node_modules structure for the accompanying binary and executes that binary with the necessary start parameters.
An example would be
"test": "mocha --reporter spec test"
when you issue "npm test", NPM will look for the mocha binary in your node_modules structure. NPM finds mocha initiates the call, passing the reporter command arg (--reporter spec) and the name of the file to be read and executed for the test.
I have some mocha tests that I run from a docker container which tests some services in other running docker containers.
Right now, I have a shell script that finds all the mocha js files, de-newlines them and passes them as an argument to mocha itself. That script then gets run in a docker container as the dockerfile CMD.
This works ok, but it is kind of hacky and is starting to get ugly with several dozen js files.
In javaland, I'd let maven run these, but I figure there must be something better suited for node/javascript.
You can either use mocha --recursive path/to/tests if you want recursively go through all folders and run all files as tests, or you can use globs to pass to mocha like mocha tests/**/test-*.js to filter out specific files matching a pattern.