gotwarlost / istanbul

Yet another JS code coverage tool that computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Supports all JS coverage use cases including unit tests, server side functional tests and browser tests. Built for scale.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

getting `istanbul cover` to show 0% coverage for files with no tests

luisonthekeyboard opened this issue · comments

Hi,

I was very reluctant to open this issue -- it's more of a question really -- but I cannot find an answer to it anywhere. And it seems such a basic thing that I'm sure I'm just missing something in here...

If I have a node project with a couple of .js files. And I have created a single test file which tests a couple of functions from one file only.

The test is a jasmine test, inside test directory, which is run by doing jasmine test. I get my 2 tests, 2 assertions, all ok.

Now I want to get coverage data for my code.

I do istanbul cover jasmine-node -- test and I get coverage results only for the .js file I tested, i.e., I'm getting 83% coverage when in fact there's one file in there that's not even being tested.

So, am I doing this wrong or do I have the wrong expectation here?

Is there a way to get istanbul cover to give me results which reflect also the files which weren't tested?

Many thanks,
L.

Sorry, somehow this issue fell through the cracks.

Yes, that is expected behavior. istanbul works by hooking require so if a file is never require-d it is as if it doesn't exist.

You could work around this issue by requir-ing all files in your codebase using some generic code in a test case. Let me know if you still want to re-open this issue.

commented

This one confused me a lot too. It doesn't seem like the coverage report is much use if its leaving out files that are untested. The purpose of the report, at least for my use case, is to see where code is and isn't covered to inform tasks to go and cover a section of code that isn't being covered.

I would expect my instrumented code to include all of the code I want reported, and the report to show me a line item for each instrumented file and their corresponding coverage - showing 0% coverage for files with 0 coverage.

This is a great tool but unfortunately i'll have to find something else because of this issue.

Maybe what you're looking for is the includeUntested option. I set that to true and get a full report for all of my files.

@domrein where did you find the includeUntested option and how are you setting it? I don't see it mentioned anywhere in the documentation

@morficus you can find it in help, istanbul help cover, if you are using cli, just pass in option --include-all-sources true.

@morficus @domrein probably used gulp-istanbul. I've seen it there where it does some foo as a workaround to require all source files. I don't think its a standard. I've not tried but maybe: 'include-all-sources': true helps.

commented

Having the same issue include-all-sources': true does not help.

any help !!

my karma.config

`module.exports = function(config) {
config.set({

    basePath: '.',

    frameworks: ['jasmine'],

    files: [
        // paths loaded by Karma
        {pattern: 'node_modules/angular2/bundles/angular2-polyfills.js', included: true, watched: true},
        {pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true},
        {pattern: 'node_modules/rxjs/bundles/Rx.js', included: true, watched: true},
        {pattern: 'node_modules/angular2/bundles/angular2.dev.js', included: true, watched: true},
        {pattern: 'node_modules/angular2/bundles/testing.dev.js', included: true, watched: true},
        {pattern: 'node_modules/angular2/bundles/http.dev.js', included: true, watched: true},
        {pattern: 'karma-test-shim.js', included: true, watched: true},

        // paths loaded via module imports
        {pattern: 'dist/**/*.js', included: true, watched: true},

        // paths to support debugging with source maps in dev tools
        {pattern: 'src/**/*.ts', included: false, watched: false},
        {pattern: 'dist/**/*.js.map', included: false, watched: false}
    ],

    // proxied base paths
    proxies: {
        // required for component assests fetched by Angular's compiler
        '/src/': '/base/src/'
    },

    port: 9876,

    logLevel: config.LOG_INFO,

    colors: true,

    autoWatch: true,

    browsers: ['Chrome'],

    // Karma plugins loaded
    plugins: [
        'karma-jasmine',
        'karma-coverage',
        'karma-chrome-launcher'
    ],

    // Coverage reporter generates the coverage
    reporters: ['progress', 'dots', 'coverage'],

    // Source files that you wanna generate coverage for.
    // Do not include tests or libraries (these files will be instrumented by Istanbul)
    preprocessors: {
        'dist/**/!(*spec).js': ['coverage']
    },

    coverageReporter: {
        reporters:[
            {type: 'json', subdir: '.', file: 'coverage-final.json'}
        ]
    },

    singleRun: true
})

};
`

Does any other coverage reporter works better than istanbul?

It is important for us to get coverage of non tested files.

@shaikhspear16 Don't know what you mean that it doesn't work? What are you trying to achieve?

have you tried the code below?

        coverageReporter: {
            includeAllSources: true,
            reporters:[
                {type: 'json', subdir: '.', file: 'coverage-final.json'}
            ]
        }

I know this thread is old (and closed), but I wanted to add another possible solution for the benefit of people arriving here via google. Using --include-all-sources gave weird coverage stats for the untested files for me and I didn't want to just require all my sources, as that would give false results for the coverage (initialisation code in those modules would make it look like those files were partly covered). My solution does need quite a few steps though:

  1. Write a test that requires all the source files, and run just this test (and record coverage).
  2. Zero out all the coverage values in the resulting file.
  3. Run the real tests and record coverage.
  4. Merge the zero'ed out coverage file with the real coverage file. This gives you a file that contains all your sources, but the untested ones will show up as zero.

You can see this in action here (hacky but working): https://github.com/tstibbs/os-map/blob/50b6ae026a261927d1d9cbd0f4fa88252c6ec014/package.json#L6

where should the --include-all-sources option go at the command line?

@ORESoftware The --include-all-sources option is an option for the command cover. You can see this by typing in istanbul help cover and it will list the options for this command. So you put the option just after you specify cover just like any other options (e.g. the --root option).

I use mocha, es6 and want to run all coverage inside my /src folder on a windows PC (have to specify full _mocha path or it errors).

Here's what I use:
"test": "babel-node ./node_modules/babel-istanbul/lib/cli.js cover --include-all-sources --root ./src ./node_modules/mocha/bin/_mocha -- --opts ./mocha.opts"

Set up istanbul-instrumenter-loader for use with TypeScript and webpack.

easy way to get 0% coverage.

add following function to core.js in istanbul middleware.

function createNonTestedFilesCoverage(opts){
console.log("opts for testing");
console.log(opts.staticdir);
var allFiles=walkSync(opts.staticdir,[]);
for(var i=0;i<allFiles.length;i++){
var contents = fs.readFileSync(allFiles[i], 'utf8');
var datastr=contents.toString();
var covStubRE = /{."path"."fnMap"."statementMap"."branchMap".*}/g;
var covStubMatch = covStubRE.exec(datastr);
var coverage1 = getCoverageObject();
if (covStubMatch !== null) {
var covStub = JSON.parse(covStubMatch[0]);
console.log(covStub);
var coverage1 = getCoverageObject();
coverage1[covStub.path]=covStub;
}
}
console.log(allFiles.length);
}

call above function in post method in handler.js in istanbul-middleware folder.

and finally provide "staticdir: your path//public-coverage" inside coverage.createHandler function in express file.

run express file and run your test cases and you will get all 0% coverage in your report.

I have taken few changes from gulp-istanbul and solved the above issue by modifying code in istanbul-middleware. Please go through the below link:

http://litutech.blogspot.in/2017/09/adding-0-coverage-in-istanbul-code.html

So does it mean that Istanbul don't work at all with ES Modules that use import instead of require? I have 0% after refactored into ES modules.

commented

I really think the istanbul maintainers should reopen this issue. If I have one file tested with 100% coverage in a project of 10 files, the other 9 files should at least report 0%, giving me a combined total of 10% coverage. But it gives me 100% instead 😳 .

I realize Istanbul needs the files to actually be imported somewhere to know they exist. So is there some way we could specify the files we'd like coverage for that will be automatically added to the overall coverage percentage (even if they don't have tests)?

@gotwarlost already made a great suggestion in #112 (comment) on how to work around this issue

You could work around this issue by requir-ing all files in your codebase using some generic code in a test case.

It's what I've been doing for my projects. But why couldn't this workaround be implemented into istanbul?