Search code examples
angularjskarma-runnerwebpackkarma-coverage

How to split code coverage by separate files for Angular, Karma and Webpack?


How can I split the coverage by separate files? Right now everything is working fine with the bundle file. I am using Angular, Webpack for bundling and Karma/Mocha/Chai for testing.

I have the following webpack.config:

module.exports = {
    entry: {
        public: "./application/src/public.js",
        office: "./application/src/office.js"
    },
    output: {
        path: "./client/javascripts/",
        filename: "[name].js",
        sourceMapFilename: "[name].js.map"
    }
};

and following karma.conf.js:

module.exports = function(config) {
config.set({
    basePath: "",
    frameworks: ["mocha", "chai"],
    reporters: ["mocha", "coverage"],
    files: [
        "./client/libs/angular/angular.js",
        "./client/libs/angular-route/angular-route.js",
        "./client/libs/angular-animate/angular-animate.js",
        "./client/libs/angular-cookies/angular-cookies.js",
        "./client/libs/angular-mocks/angular-mocks.js",
        "./client/libs/angular-messages/angular-messages.js",
        "./client/javascripts/office.js", /* the bundle */
        "./application/**/*_tests.js"
    ],
    preprocessors: {
        "./client/javascripts/office.js": ["coverage"]
    },
    coverageReporter: {
        type: "html",
        dir: "coverage/"
    },
    exclude: [],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ["PhantomJS"],
    singleRun: false
});
};

sample test file:

describe("AccountLoginCtrl", function() {
        beforeEach(angular.mock.module("stAccount"));

        var $controller;
        var AccountLoginCtrl;
        var $scope;

        beforeEach(angular.mock.inject(function(_$controller_) {
            $controller = _$controller_;
            $scope = {};
            AccountLoginCtrl = $controller("AccountLoginCtrl", {
                $scope: $scope
            });
        }));

        it("should exist", function() {
            expect(AccountLoginCtrl).to.exist;
        });
    });

Solution

  • Settup your folder structure:

    karma.conf.js
    ./application
        ./src
            ./components
            entry.js
        ./tests
            index.js
            ./components
        ./coverage
    

    Add index.js in the tests folder as an entry point for the tests.

    // adds all test files to the bundle.
    var testsContext = require.context("./components", true, /\.js$/);
    testsContext.keys().forEach(testsContext);
    
    // adds the application to the bundle.
    var componentsContext = require("../src/entry"); 
    

    karma.conf.js

    var path = require("path");
    module.exports = function(config) {
        config.set({
            basePath: "",
            frameworks: ["mocha"],
            reporters: ["mocha", "coverage"],
            files: [
                "./client/libs/angular/angular.js",
                "./client/libs/angular-route/angular-route.js",
                "./client/libs/angular-animate/angular-animate.js",
                "./client/libs/angular-cookies/angular-cookies.js",
                "./client/libs/angular-mocks/angular-mocks.js",
                "./client/libs/angular-messages/angular-messages.js",
                "./application/tests/index.js",
            ],
            preprocessors: {
                "./application/tests/index.js": ["webpack"]
            },
            webpack: {
                module: {
                    preLoaders: [
                        {
                            test: /\.js$/,
                            include: path.resolve("./application/src/"),
                            loader: "isparta"
                        }
                    ]
                }
    
            },
            webpackMiddleware: {
                noInfo: true
            },
            coverageReporter: {
                type: "html",
                dir: "./application/coverage/"
            },
            exclude: [],
            port: 9876,
            colors: true,
            logLevel: config.LOG_INFO,
            autoWatch: true,
            browsers: ["PhantomJS"],
            singleRun: false
        });
    };
    

    package.json

    {
    "devDependencies": {
        "chai": "^3.4.0", 
        "isparta-loader": "^1.0.0",
        "karma": "^0.13.12",
        "karma-coverage": "^0.5.3",
        "karma-mocha": "^0.2.0",
        "karma-mocha-reporter": "^1.1.1",
        "karma-phantomjs-launcher": "^0.2.1",
        "karma-webpack": "^1.7.0",
        "mocha": "^2.3.3",
        "phantomjs": "^1.9.18",
        "webpack": "^1.12.2"
      }
    }