15

I am using gulp-istanbul to generate JavaScript unit test coverage reports through Gulp. Is there a way to configure Istanbul to generate a full coverage report of all the JS files in my gulp stream, and not just the files touched by a test case.

I'm working on a project with a lot of JS, but no unit tests, and we are trying to increase the test coverage. I would like to have a coverage report that starts by show 0% coverage for most of our files, but over time will present an increasing coverage percentage.

gulp.task( 'test', function () {
    gulp.src( [ my source glob ] )
        .pipe( istanbul() )
        .on( 'end', function () {
            gulp.src( [ my test spec glob ] )
                .pipe( mocha( {
                    reporter: 'spec'
                } ) )
                .pipe( istanbul.writeReports(
                    [ output location ]
                ) );
        } );
} );
Scott
  • 2,233
  • 2
  • 15
  • 8
  • I know you have fixed you problem but check my answer, it seems that they've added a simpler method, straight into gulp-istanbul. Might be worth checking it out / confirming it gives the same results. – Romain Braun Oct 17 '14 at 06:02

4 Answers4

15

It actually is much more simple now and you just have to add includeUntested to your istanbul() call.

gulp.task('test', function () {
    return gulp.src('./assets/**/js/*.js')
      // Right there
      .pipe(istanbul({includeUntested: true}))
      .on('finish', function () {
        gulp.src('./assets/js/test/test.js')
          .pipe(mocha({reporter: 'spec'}))
          .pipe(istanbul.writeReports({
            dir: './assets/unit-test-coverage',
            reporters: [ 'lcov' ],
            reportOpts: { dir: './assets/unit-test-coverage'}
          }));
      });
  });

Source : https://github.com/SBoudrias/gulp-istanbul#includeuntested

Romain Braun
  • 3,624
  • 4
  • 23
  • 46
  • A critical part I found with this answer is the fact that you are returning gulp.src(...). – AJ X. Feb 25 '17 at 14:01
  • @axlj As far as I remember I think it's just to help gulp compute the time it takes each task to run. Otherwise you end up with things like "finished test after 3 μs" – Romain Braun Mar 10 '17 at 09:44
4

Istanbul hook is executed when the file is required. So, you need to require all files in order for them to be included in the final coverage report. You can achieve this by injecting a tap inside your gulp task and call require on all selected files:

gulp.task( 'test', function () {
    gulp.src( [ my source glob ] )
        .pipe( istanbul() )
        .pipe(tap(function(f) {
            // Make sure all files are loaded to get accurate coverage data
            require(f.path);
        }))
        .on( 'end', function () {
            gulp.src( [ my test spec glob ] )
                .pipe( mocha( {
                    reporter: 'spec'
                } ) )
                .pipe( istanbul.writeReports(
                    [ output location ]
                ) );
        } );
} );
msanford
  • 11,803
  • 11
  • 66
  • 93
Joel Grenon
  • 3,173
  • 1
  • 19
  • 19
  • gulp-tap throws this error `no writecb in Transform class` and I can't figure out why. The rest of the code works perfectly. Any idea? – Romain Braun Oct 17 '14 at 05:54
4

I've been struggling with this today and found no answers on Google. I finally came up with an answer very similar to an answer here but the writeReports call must go before the call to mocha.

gulp.task('test', ['build'], function(done) {
  gulp.src('lib/**/*.js')
    .pipe($.istanbul({ includeUntested: true }))
    .on('end', function() {
      gulp.src(['test/helpers/**/*.coffee', 'test/spec/**/*.coffee'])
        .pipe($.istanbul.writeReports({
          dir: './coverage',
          reportOpts: {
            dir: './coverage'
          },
          reporters: ['html']
        })).pipe($.mocha({
          reporter: 'spec',
          require: 'coffee-script/register'
        }));
    });
});

There is a ticket related to this which I found referenced in the gulp-istanbul code just before some voodoo magic to make things work: https://github.com/gotwarlost/istanbul/issues/112

bline
  • 41
  • 2
3

to show the coverage in all files you must do 2 things:

  • All files in the project should be included in the [my source glob].

  • All files must be required, in other words, the require() must be called on all files in the project, because istanbul probably changes the default require() in order to calculate the coverage in a file.

You can write something like this at the start of the test file:

for([all .js files in project]){
  require([file])
}

You can use require-dir for that.

And use this instead:

var requireDir = require('require-dir');
var dir = requireDir('./projectFolder', {recurse: true});
OmarCastro
  • 86
  • 2