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.
Other
8.7k stars 786 forks source link

Theoretical Question: What should I do about coverage on app initialization scope? #839

Open jt000 opened 7 years ago

jt000 commented 7 years ago

I have a pattern in my code where I create a function scope to initialize by angular components. I believe this to be a pretty common pattern, but it creates coverage details that aren't covered by unit tests (and can't be afaik).

For example, take the following service creation in angular 1:

(function() {
    'use strict';

    angular
        .module('myApp')
        .factory('myService', ['$rootScope', '$http', '$q', myService]);

    function myService($rootScope, $http, $q) {

        var services = {
            compute: compute
        };

        return services;

        function compute() {
            // do some stuff...
        }
    }
})();

Without writing a single unit test, istanbul tells me that I have roughly 40% code coverage just due to the call to angular.module(...).factory(...). While this isn't necessarily wrong (the code was executed during the tests), it does pose a couple of questions:

  1. Should the initialization code be placed somewhere that can be tested in a unit test? How?
  2. Should I accept the coverage results as valid since the code is being exercised (despite it not being exercised in a unit test)?
  3. Should I exclude the initialization code from coverage since it can't be tested in a unit test?
jt000 commented 7 years ago

What are your thoughts on adding something that would a) disable reporting initially and b) enable reporting at runtime (i.e. after JS files are loaded, but before any tests are run)?

For example, if istanbul reporting was disabled in the reporter config:

        coverageReporter: {
            // Disables the coverage reporter preventing lines from being tracked as covered causing
            // a 0% coverage on all instrumented code unless enabled at runtime.
            enabled: false, 

            dir: '.tmp/coverage/',

            reporters: [
                {type: 'text'},  // output to console
            ],

            check: {
                global: {
                    statements: 100,
                    lines: 100,
                    functions: 100,
                    branches: 100
                }
            }
        },

Then during the tests (presumably in a call to beforeAll) istanbul's coverage reporter could be enabled. This allows all files to be loaded and initialized with 0 code coverage and only reporting coverage tracked during unit testing.

beforeAll(function() {
    var istanbul = require('istanbul');
    istanbul.enabled(true);
});