Mocha with Blanket, Babel and LCOV reporter - javascript

Hiho,
I've got a problem with my Mocha configuration. I've got ES6 code which should be compiled by Babel and then I want to get coverage (in LCOV format) of this ES6 code.
My approach to this problem was to use mocha, mocha-lcov-reporter, babel and blanket packages. Code structure is:
-- src
----- ...
-- test
----- spec
-------- something.spec.js
-------- ...
----- blanket.js
Where specs are in test/spec directory (matches also *.spec.js pattern) and blanket.js is:
require('blanket')({
pattern: require('path').join(__dirname, '..', 'src')
});
Command which I prepared is:
./node_modules/.bin/mocha $(find test -name '*.spec.js') --recursive --compilers js:babel/register -r test/blanket -R mocha-lcov-reporter
So, it should run Mocha tests for all *.spec.js files, compiling them by Babel and starting test/blanket.js file before.
After starting this command I get Error: Line 1: Unexpected reserved word error from esprima.js. When I run it without requiring test/blanket file it run without problems, but ofc I haven't coverage.
Has anyone tried to do so? Do you have any ideas how to do it?

Okey, problem already resolved, but without Babel (native ES6 instead); I've done it another way. I've used istanbul-harmony and mocha packages. Then the command is:
./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- $(find test -name '*.spec.js') -R spec -u exports

Related

How to get nyc coverage to work with es6 import (.mjs files)

I've typically used nyc to provide coverage for my unit tests. All honkey dorey for pre-ES6 require('myModule') tests. I'm having trouble getting it to work with unit tests that use ES6 import. Tests without coverage work with --experimental-modules and .mjs files:
package.json
"scripts": {
"test": "node --experimental-modules ./test/test.mjs",
... others deleted to save space
},
And everything works. I'm using Tape for testing if that matters. Output looks like:
(node:9360) ExperimentalWarning: The ESM module loader is experimental.
TAP version 13
# number
ok 1 should be equal
(... more deleted)
But when I try to use nyc, e.g. nyc --reporter=lcov --extension .mjs npm test
I get an error:
(node:7304) ExperimentalWarning: The ESM module loader is experimental.
Error [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension: C:/Users/Morgan/.node-spawn-wrap-6952-61a26e1bb867/node
at exports.resolve (internal/loader/ModuleRequest.js:126:13)
at Loader.resolve (internal/loader/Loader.js:48:40)
....
I'm using node version 8.9.1 and nyc version 13.0.1, running on Windows.
As the documentation states, .mjs support should be explicitly added:
Supporting file extensions can be configured through either the
configuration arguments or with the nyc config section in package.json.
nyc --extension .mjs npm test
{
"nyc": {
"extension": [
".mjs"
]
}
}

babel compiler with cucumber.js version 4

with cucumber#1, I could run tests that needed transpiling like this
cucumberjs --compiler js:babel-core/register
but that doesn't work with cucumber#4
node_modules/.bin/cucumber-js --help
doesn't list the --compiler option anymore
it doesn't complain when I put the option in, but when it gets to the first jsx angle bracket, it complains.
When you run node_modules/.bin/cucumber-js --help you can see that the option to require a node module before requiring files is --require-module so an example would be ./node_modules/.bin/cucumber-js --require-module #babel/register test/features

How can mocha recursively search my `src` folder for a specific filename pattern?

In my npm package, I would like to emulate the pattern Meteor follows: a source file (named client.js) has a test file (named client.tests.js) live in a src/ folder. Tests run with the npm test command.
I'm following the usage docs to the 't'. I do not want to use a find in my package test command.
I understand that mocha can recursively execute tests:
mocha --recursive
I understand that mocha can execute tests in a specific subfolder using the --recursive flag:
mocha src --recursive
I also understand that I can specify a glob to filter files by passing *.tests.js:
mocha *.tests.js
But, I want all three. I want mocha to test only files ending in tests.js in the src folder, recursively checking subdirectories.
mocha --recursive *.tests.js
// See the files?
$ > ll ./src/app/
total 168
-rw-r--r-- ... client.js
-rw-r--r-- ... client.tests.js
// Option A
$ > mocha --recursive *.tests.js
Warning: Could not find any test files matching pattern: *.tests.js
No test files found
// Option B
$ > mocha *.tests.js --recursive
Warning: Could not find any test files matching pattern: *.tests.js
No test files found.
// Option C
$ > mocha --recursive src/app/*.tests.js
3 passing (130ms)
3 failing
So...
Why is mocha not picking up the *.tests.js files in the subfolders?
Why DOES it work if I specify the full path to the file?
How do I make it work as desired?
The --recursive flag is meant to operate on directories. If you were to pass a glob that matches directories, then these directories would be examined recursively but if you pass a glob that matches files, like you are doing, then --recursive is ineffective. I would suggest not using --recursive with a glob because globs already have the capability to look recursively in subdirectories. You could do:
mocha 'src/app/**/*.tests.js'
This would match all files that match *.tests.js recursively in src/app. Note how I'm using single quotes around the pattern. This is to quote the pattern so that it is passed as-is to Mocha's globbing code. Otherwise, your shell might interpret it. Some shells, depending on options, will translate ** into * and you won't get the results you want.

How to use babel in combination with coffee-script in my mocha tests

I like to write my unit test with coffee-script and use mochajs as a framework.
I use following settings to configure mocha to use coffee-script.
node ./node_modules/mocha/bin/mocha ./tests/ --compilers coffee:coffee-script/register --reporter spec
Unfortunately registering two compilers doesn't work.
node ./node_modules/mocha/bin/mocha ./tests/ --compilers coffee:coffee-script/register, js:babel-core/register --reporter spec
assuming that js-files will be transpiled with babel and coffee-files will be handled with coffee-script. But does not seam to work.
My production code (which I want to test) is written in es6 and transpiled with babel in webpack.
How would I set up mocha so that the production code will be transpiled from es6 and can be used in my coffee-script tests?
//EDIT
To extend the question and explain it in detail I just added a sample
I have a code file in JS es6
//hello.js
const hello = (msg) =>{
return msg;
}
export default hello;
my coffee script test looks like this
#test1.coffee
should = require "should"
hello = require "./hello"
describe "Given I have an es6 module",->
it "it should be possible to test it with mocha and coffeescript",->
a = hello
should.exist a
it "it should also print out the given message",->
msg = hello "world"
msg.should.eql "world
my .babelrc looks like this
//.babelrc
{
"presets":["es2015"],
"plugins": ["transform-es2015-modules-commonjs"]
}
My test output looks like this.
Given I have an es6 module
✓ it should be possible to test it with mocha and coffeescript
1) it should also print out the given message
1 passing (11ms)
1 failing
1) Given I have an es6 module it should also print out the given message:
TypeError: hello is not a function
at Context.<anonymous> (test1.coffee:10:11)
It looks like the hello.js module is imported (required) but will not be transformed into a commonjs module.
when I console.log hello -> I get { default: [Function: hello] }
my tests are executed with npm test test1.coffee
And my current call from packages.json is:
"scripts": {
"test": "./node_modules/mocha/bin/mocha --compilers js:babel-core/register --require babel-polyfill --require coffee-script/register --reporter spec --recursive"
},
Any advice how to setup mocha to compile es6 on-the-fly and run the coffeescript tests would be much appreciated.

How to configure istanbul coverage report to exclude certain sources?

I'm developing a nodeJS + angular stacked application. To generate the code coverage reports for the backend I use istanbul and mocha. However, the coverage reports show incorrect figures.
If I run istanbul cover _mocha --print detail /path/to/tests* I get full coverage (but only on the file that is requires by the test spec). On the other hand if I run istanbul cover _mocha --print detail --include-all-sources /path/to/tests* istanbul also checks the test coverage for the frontend code (angular, which I test with karma/jasmine separately).
How do I run istanbul so it includes only the backend source files?
According to istanbul help cover output
$ ./node_modules/.bin/istanbul help cover
Usage: istanbul cover [<options>] <executable-js-file-or-command> [--<arguments-to-jsfile>]
Options are:
--config <path-to-config>
the configuration file to use, defaults to .istanbul.yml
--root <path>
the root path to look for files to instrument, defaults to .
-x <exclude-pattern> [-x <exclude-pattern>]
one or more glob patterns e.g. "**/vendor/**"
-i <include-pattern> [-i <include-pattern>]
one or more glob patterns e.g. "**/*.js"
--[no-]default-excludes
apply default excludes [ **/node_modules/**, **/test/**,
**/tests/** ], defaults to true
--hook-run-in-context
hook vm.runInThisContext in addition to require (supports
RequireJS), defaults to false
--post-require-hook <file> | <module>
JS module that exports a function for post-require processing
--report <format> [--report <format>]
report format, defaults to lcov (= lcov.info + HTML)
--dir <report-dir>
report directory, defaults to ./coverage
--print <type>
type of report to print to console, one of summary (default),
detail, both or none
--verbose, -v
verbose mode
--[no-]preserve-comments
remove / preserve comments in the output, defaults to false
--include-all-sources
instrument all unused sources after running tests, defaults to
false
--[no-]include-pid
include PID in output coverage filename
You should use the -X to exclude some files from coverage reporting. i.e:
$ ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha test -X dist/index.js
Will execute the test, and ignore the dist/index.js file on coverage reporting
Do you have your backend code and your frontend code in separate directories? For example /test/api and /test/dashboard or whatever. If you keep your code separate, you can tell istanbul to report on each at a time like so:
istanbul cover _mocha test/api/**/*.js
Makes sense? Would that work for you at all?
Let me know.
I also faced a similar situation and hence thought it's worth sharing if it could help someone though its an old post. Istanbul takes the current directory (.) as a coverage directory while running the command. In order to include just a specific directory to coverage scope use "--root /dir/" option. This would generate coverage report only for the files in that directory.

Categories