blanket
blanket copied to clipboard
How to show 0% for untested files (node + mocha)?
I'm using: node v0.10.21 mocha 1.10.0 blanket 1.1.6
With following configured in package.json
"scripts": {
"test": "mocha test/server -R spec --recursive",
"test-cov": "mocha --require blanket test/server -R html-cov --recursive > coverage.html"
},
"config": {
"blanket": {
"pattern": "server"
}
}
Then I run npm run-script test-cov
It doesn't show coverage for files that are missing tests completely.
Is it possible to configure blanket to show 0% for those files? (and factor into the overall coverage?)
Noticed this because the total coverage reported (97%) was higher than expected, but then realized it seems to not report on files that don't have any spec at all.
I found the same issue.
var blanketRequired = false;
if (requireArgPosition &&
args[requireArgPosition + 1] &&
args[requireArgPosition + 1].match('blanket')) {
blanketRequired = true;
}
This is not a safe way to judge using mocha cli or not. Sometimes args can be: [ 'node', 'C:\Users\miniflycn\AppData\Roaming\npm\node_modules\mocha\bin_mocha', '--require', 'should', '--timeout', '5000', '--require', 'blanket', '-R', 'html-cov' ]
See also #367
Basically, to get coverage for files that are not tested, you need to manually load them somehow so that blanket becomes aware of them.
Without knowing the specifics of your project, it would be something like:
function parseDir(curr){
if (curr is a file){
require(curr);
else if (curr is a directory){
parseDir(curr.files);
}
}
you do nothing with the requires, but it will instrument the files so they show up in the blanket report.
I had the same problem; based on these comments I wrote a small function to include all files within one or more directories (largely based on http://stackoverflow.com/questions/7041638/walking-a-directory-with-node-js ). Perhaps it saves someone some time, see below.
I've put this script it in a blanket.js file in the root directory which is automatically loaded by blanket.js before it goes to work.
It feels a bit odd to have to do this manually, you'd expect when setting a 'pattern' it would include all files in the coverage that satisfy that pattern, regardless of inclusion or not. Not sure why that is... I discovered this behaviour only by accident.
(I also had troubles getting the blanket pattern config to load like in the examples; the coverage stayed at 0%. As a work-around I set the blanket configuration below manually)
The function below only works on directories relative to the root directory; not sure what other patterns blanket allows; for me it was sufficient.
'use strict';
/**
* This file is loaded by blanket.js automatically before it instruments code to generate a code coverage report.
*/
var fs = require('fs');
var log = require('winston');
var packageJson = require('./package.json');
// For some reason the blanket config in package.json does not work automatically, set the settings manually instead
require('blanket')({
// Only files that match this pattern will be instrumented
pattern: packageJson.config.blanket.pattern
});
/**
* Walks through a directory structure recursively and executes a specified action on each file.
* @param dir {(string|string[])} The directory path or paths.
* @param action {function} The function that will be executed on any files found.
* The function expects two parameters, the first is an error object, the second the file path.
*/
function walkDir(dir, action) {
// Assert that action is a function
if (typeof action !== "function") {
action = function (error, file) {
};
}
if (Array.isArray(dir)) {
// If dir is an array loop through all elements
for (var i = 0; i < dir.length; i++) {
walkDir(dir[i], action);
}
} else {
// Make sure dir is relative to the current directory
if (dir.charAt(0) !== '.') {
dir = '.' + dir;
}
// Read the directory
fs.readdir(dir, function (err, list) {
// Return the error if something went wrong
if (err) return action(err);
// For every file in the list, check if it is a directory or file.
// When it is a directory, recursively loop through that directory as well.
// When it is a file, perform action on file.
list.forEach(function (file) {
var path = dir + "/" + file;
fs.stat(path, function (err, stat) {
if (stat && stat.isDirectory()) {
walkDir(path, action);
} else {
action(null, path);
}
});
});
});
}
};
// Loop through all paths in the blanket pattern
walkDir(packageJson.config.blanket.pattern, function (err, path) {
if (err) {
log.error(err);
return;
}
log.error('Including ' + path + ' for blanket.js code coverage');
require(path);
});
This workaround is what I have used in the past. I understand the confusion though. The problem is that Blanket does not load files directly, it just intercepts the loading of files. So, if you wanted Blanket to instrument files not referenced by tests it would require rewriting the way that Blanket instruments. It's possible, but it's a significant change.
I got same issue, please fix it.
@guileen this is the fix -> https://github.com/alex-seville/blanket/issues/361#issuecomment-34002054
@alex-seville Thank you for your hard work. Will it be merged in next release?
No, the solution lives outside of Blanket for the moment. It doesn't seem like a good idea to automatically provide coverage for all files in a project. Unless this changes, @nielskrijger's code is a good solution to your use case.
In case it's helpful to anyone... here's an example of how to incorporate something like @nielskrijger's comment: https://github.com/hammerlab/cycledash/pull/265