I'm having some issues while running Istanbul with Mocha and the Babel compiler.
All my tests are running just fine, but after all the tests done it shows me this message:
No coverage information was collected, exit without writing coverage information
And it is not producing any coverage report.
The command that I am running is:
NODE_ENV=test istanbul cover _mocha -- --require babel-core/register --recursive
The project is hosted on GitHub:
https://github.com/weslleyaraujo/react-flux-puzzle/tree/feat/unit-tests-24
Any ideas what it could be?
Using Babel 6.x, let's say we have file test/pad.spec.js:
import pad from '../src/assets/js/helpers/pad';
import assert from 'assert';
describe('pad', () => {
it('should pad a string', () => {
assert.equal(pad('foo', 4), '0foo');
});
});
Install a bunch of crap:
$ npm install babel-istanbul babel-cli babel-preset-es2015 mocha
Create a .babelrc:
{
"presets": ["es2015"]
}
Run the tests:
$ node_modules/.bin/babel-node node_modules/.bin/babel-istanbul cover \
node_modules/.bin/_mocha -- test/pad.spec.js
pad
✓ should pad a string
1 passing (8ms)
=============================================================================
Writing coverage object [/Volumes/alien/projects/forked/react-flux-puzzle/coverage/coverage.json]
Writing coverage reports at [/Volumes/alien/projects/forked/react-flux-puzzle/coverage]
=============================================================================
=============================== Coverage summary ===============================
Statements : 100% ( 4/4 )
Branches : 66.67% ( 4/6 ), 1 ignored
Functions : 100% ( 1/1 )
Lines : 100% ( 3/3 )
================================================================================
UPDATE: I've had success using nyc (which consumes istanbul) instead of istanbul/babel-istanbul. This is somewhat less complicated. To try it:
Install stuff (you can remove babel-istanbul and babel-cli):
$ npm install babel-core babel-preset-es2015 mocha nyc
Create .babelrc as above.
Execute this:
$ node_modules/.bin/nyc --require babel-core/register node_modules/.bin/mocha \
test/pad.spec.js
...which should give you similar results. By default, it puts coverage info into .nyc-output/, and prints a nice text summary in the console.
Note: You can remove node_modules/.bin/ from any of these commands when placing the command in package.json's scripts field.
PS: I now recommend to use single jest instead of mocha/instanbul/nyc/chai/etc.
Solution A: Using nyc and babel-plugin-istanbul
Setup (don't forget #next for nyc):
npm install --save-dev nyc babel-plugin-istanbul babel-register
Add an env to babel config:
{
"env": {
"nyc": { "plugins": ["istanbul"] }
}
}
nyc config:
{
"reporter" : ["text", "text-summary", "lcov", "html"],
"include" : ["src/**/*.js"],
"require" : ["babel-register"],
"sourceMap" : false,
"instrument" : false,
"all" : true
}
PS: include field needs to be specified in .nycrc of in package.json, if specified in command line, coverage will not works
Running the tests:
# 1. Build
NODE_ENV=nyc babel src --out-dir lib
# 2. Coverage
nyc mocha
Solution B: No extra packages : Only the basic ones
Work has been done recently on istanbul (1.0.0-alpha.2) to support Babel generated code with sourcemaps (see #212 and this for an example).
There are 2 ways:
A. Tests written against previously transpiled code
B. Tests written against original code and transpiled all together in memory at runtime
B1. Tests that exports (previously) transpiled code
This is done in 2 steps: Firstly, build your source with babel (e.g. from ./src to ./out) and write your tests against transpiled source (export foo from "./out/foo";).
Then you will be able to run the tests using istanbul 1.0.0-alpha.2 :
istanbul cover _mocha -- ./test --compilers js:babel-register
Now if you want code coverage to follow the original code you've written (not the transpiled one), make sure to build with babel source-maps options set to both :
babel ./src --out-dir ./out --source-maps both
PS: If needed you can also do :
istanbul cover _mocha -- ./test --compilers js:babel-register \
--require babel-polyfill \
--require should \
--require sinon
B2. Tests that directly exports original code
In this case you write your tests against original source (export foo from "./src/foo";), and with no further step, you directly run istanbul 1.0.0-alpha.2 using babel-node against cli.js :
babel-node ./node_modules/istanbul/lib/cli.js cover _mocha -- ./test
PS: If needed you can also do :
babel-node ./node_modules/istanbul/lib/cli.js cover _mocha -- ./test
--require babel-polyfill \
--require should \
--require sinon
As of now 17.4.2016 this coverage reporting stuff is still a bit messy and with my React-project that has .jsx files and a helper file the coverage reporting script looks like this:
istanbul cover node_modules/mocha/bin/_mocha -- \
--compilers js:babel-core/register \
--require ./test/testhelper.js \
\"test/**/*#(.js|.jsx)\"
So it wouldn't be too easy the current version 0.4.3 of Istanbul doesn't work with Babel so you have to use the experimental alpha-version:
npm install istanbul#1.0.0-alpha.2 --save-dev
And then you need .istanbul.yml -file so that Istanbul recognizes the .jsx-files with these lines:
instrumentation:
root: .
extensions: ['.js', '.jsx']
And now it should work. Also as a small bonus if you want to add coverage reporting with Travis and Coveralls you should:
enable the project in https://coveralls.io
add coveralls npm i coveralls --save-dev
add this to your .travis.yml:
script:
- npm --silent test
- cat ./c
coverage/lcov.info | coveralls
And now you can put that cool badge to your README. Neato!
Related
A fantastic crate is cargo watch, which allows, for example, for you to execute:
cargo watch -x run
to automatically rebuild/run on src change. This is amazing for development but one issue I have is that it seems to not support the --manifest-path argument that can be used with cargo run to explicitly specify the path to the .toml file of the project such that it can be run from a different pwd than the Cargo.toml file itself:
cargo run --manifest-path /home/user/project/Cargo.toml
The crate documentation doesn't mention anything about this, so I was wondering if anyone who uses this crate has found a way around this. When attempting to use the --manifest-path argument I receive:
error: Found argument '--manifest-path' which wasn't expected, or isn't valid in this context
USAGE:
cargo watch [FLAGS] [OPTIONS]
Which makes some sense as I know not all commands support the --manifest-path arg, but since the crate uses cargo run to run the project itself I'm guessing there is some way around this without using e.g. sh -c 'cd [path to .toml file] && cargo watch -x run'
Yes you can just use the invocation which lets you run arbitrary commands:
cargo watch -- cargo run --manifest-path=path/to/Cargo.toml
Software involved:
webpack 4.8.3
typescript 2.8.3
ts-loader 4.3.0
Webpack configuration:
rules: [
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: ['ng-annotate-loader', 'ts-loader']
},
...
]
This compiles my project fine on a single build (webpack --mode development).
However, it starts to produce errors when building in watch mode:
$ webpack --progress --watch --mode development
Webpack is watching the files…
Hash: e8f3fc158b2b6feaad07
Version: webpack 4.8.3
Time: 75713ms
Built at: 05/15/2018 3:25:27 PM
Asset Size Chunks Chunk Names
...
(The build is fine. Now I change one file, and it rebuilds:)
[./ts/foo/foo.ts] 3.82 KiB {foo} [built] [1 error]
[./ts/foo/controllers/bar.ts] 3.8 KiB {baz} {foo} [built]
[./ts/foo/baz.ts] 4.21 KiB {baz} [built] [1 error]
+ 668 hidden modules
ERROR in .../ts/foo/foo.ts
./ts/foo/foo.ts
[tsl] ERROR in .../ts/foo/foo.ts(84,9)
TS2554: Expected 0 arguments, but got 1.
ERROR in .../ts/foo/baz.ts
./ts/foo/baz.ts
[tsl] ERROR in .../ts/foo/baz.ts(105,9)
TS2554: Expected 0 arguments, but got 1.
The lines it refers to are all lines containing console.log calls, e.g.:
console.log(`Using locale ${locale}`);
Again, if I abort the watch and build from scratch, it works just fine. What's the problem here?
For testing I have removed ng-annotate-loader; no change.
This started happening after upgrading the build toolchain from Webpack 3 to 4 with associated upgrades to Typescript from 2.3.x. In the old versions build --watch works fine.
I think that the problem is related to webpack.NewWatchingPlugin (the default watching plugin), but you can force webpack to use the old file watching logic if you add new webpack.OldWatchingPlugin() plugin. The OldWatchingPlugin is more stable than NewWatchingPlugin.
There are a variety of reasons why webpack might not working properly:
If no files are outputted (with different hashes), it is likely a configuration issue, not a
file watching issue.
Having not enough file watchers causes file watcher in Webpack won't
recognize the changes.
On my build step I'm using babel to transpile the code to es5 (from src to dist). How do I make it exclude files ending in .test.js?
package.json
"scripts": {
"build": "babel src --out-dir dist",
.babelrc
{
"presets": [ "es2015" ],
"ignore": "\\.test\\.js"
}
Based on the documentation, you should be able to write .babelrc
{
"ignore": [
"**/*.test.js"
]
}
However, I was able to verify that this does not seem to work. I tried it with version 6.5.1 (babel-core 6.5.2).
At the same time, the following does work:
babel src --out-dir build --ignore '**/*.test.js'
That is the same glob pattern as written in the .babelrc file. If you install any glob library from npm you'll find that this glob pattern would work (that is how I came up with it...I do not currently use babel).
As of today, the following works in .babelrc
(babel-core: v6.26.3)
"ignore": [
"**/__tests__", // ignore the whole test directory
"**/*.test.js" // ignore test files only
]
I'm working on a project split across multiple crates. The top-level crate (the app) requires the two other crates (libraries) as dependencies. Running cargo test in the top-level crate builds the dependencies and runs tests for the top-level crate, but it doesn't run tests for the two other crates. Is there a way to configure cargo test so that it will run tests in all three crates?
Thanks!
You can pass the -p parameter to make Cargo run the tests of a dependency.
So, if your crate is called sublib, you can run its tests using:
cargo test -p sublib
From cargo test --help:
-p SPEC, --package SPEC Package to run tests for
If the --package argument is given, then SPEC is a package id
specification which indicates which package should be tested. If it is
not given, then the current package is tested. For more information on
SPEC and its format, see the cargo help pkgid command.
As Grunt doesn't support only rebuilding what has changed, I'd like to wrap a Makefile around it, to just compute the set of "input" files and not invoke grunt at all, unless any of them have changed since last build.
Can you tell grunt to just list what files a given task would depend on on stdout somehow?
You could do this with a custom task though it would still be wrapped by normal grunt output.
grunt.registerTask('src', function(){
var taskConfig = grunt.config(this.args.join('.'));
var expanded = grunt.task.normalizeMultiTaskFiles(taskConfig);
expanded.forEach(function(files){
files.src.forEach(function(file) {
console.log(file);
});
});
});
Command line syntax to list all files for, say, a subtask for jshint called "myFiles" would be grunt src:jshint:myFiles
$ grunt src:jshint:myFiles
Running "src:jshint:myFiles" (src) task
file1.js
file2.js
dir/file3.js
Done, without errors.
Based on jsoverson's answer, I managed to cobble together a proof-of-concept that defers dependency tracking to the Gruntfile, so I can add Makefile rules that invoke the grunt bits to build the project. This project uses coffee-script (use http://js2coffee.org/ to convert to js if you want to reuse this for some non-coffee project), so in my Gruntfile.coffee I added
gruntGetPaths = (fn) -> ->
taskConfig = grunt.config #args.join '.'
grunt.task.normalizeMultiTaskFiles(taskConfig)
.forEach fn ? (files) ->
files.src.forEach (path) ->
console.log path
grunt.registerTask 'src', gruntGetPaths
grunt.registerTask 'dst', gruntGetPaths (files) -> console.log files.dest
giving me the grunt src:... and grunt dst:... rules that produce grunt-junk-wrapped file lists.
It seems the junk is guaranteed to be colorized / adds a trailing empty line (at least with grunt v0.4.1 / grunt-cli v0.1.9), so chopping that off by piping their output to egrep -v '\e|^$' worked.
Near the top of my Makefile I added some macros for that:
define GRUNT
$(shell grunt --no-write $1 | egrep -v '\e|^$$')
endef
define SRC
$(call GRUNT,src:$1)
endef
define DST
$(call GRUNT,dst:$1)
endef
...and then rules that borrow knowledge from the Gruntfile:
$(call DST,stylus:compile): coffee $(call SRC,stylus:compile)
grunt stylus
$(call DST,coffee:glob_to_multiple): coffee $(call SRC,coffee:glob_to_multiple)
grunt coffee
$(call DST,uglify:my_target): coffee $(call SRC,uglify:my_target)
grunt uglify
coffee:
npm install 2>&1 | tee $#
...which has corresponding setup looking like this:
#initConfig
pkg: grunt.file.readJSON "package.json"
stylus:
compile:
options:
paths: ["src/stylus/"]
import: ["nib"]
files:
"stylesheets/foo.css": "src/stylus/foo.styl"
"stylesheets/foo-dev.css": ["src/stylus/foo.styl", "src/stylus/foo-dev.styl"]
coffee:
glob_to_multiple:
expand: true
cwd: 'src/coffee/'
src: ['*.coffee']
dest: 'javascripts/'
ext: '.js'
uglify:
my_target:
files:
"javascripts/foo.min.js": ["javascripts/foo.js"]
This works, but is slow. Given a bare grunt stylus run that takes 2.94s to run, running these make rules to regenerate css takes another 5.41s of pure overhead, which is sort of horrible - and if I nuke all the generated files and try to regenerate the min.js, there is no dependency resolution as the glob rules can't be traced back to find all intermediate files.
So while it's possible to do this, it did not end up being a solution to the problem "running grunt is slow and stupid, when no source files have changed", as running grunt stylus coffee uglify in this project takes 3.25 seconds to reproduce what was already there, and a bare make run that just resolves dependencies and finds nothing relevant changed takes over five.
It would of course be great if grunt had its own dependency management to know when it can exit immediately, like our grandfather's tools would. :-)