Izhaki
Izhaki

Reputation: 23586

Getting karma server to launch upon grunt watch

While developing, I'm using karma and grunt to watch for file changes and run the tests.

In command line, I'd like to be able to simply enter

$ grunt watch

and have the karma server to start once, and thereafter having grunt watching for changes and running the various tasks (including karma tests) whenever files change. I don't want to enter $ karma start .

How can this be achieved?

Upvotes: 2

Views: 1510

Answers (1)

Izhaki
Izhaki

Reputation: 23586

Option #1

One can use the atBegin option of grunt-contrib-watch. The idea is to introduce a startup task, which will run at the startup of the watcher:

watch: {
    startup: {
        files: [], // This is redundant, but we get an error if not specifying files.
        tasks: [ 'karma:continuous:start' ],
        options: {
            atBegin: true,
            spawn: false
        }
    },

    ...
}

The full Gruntfile.js:

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        karma: {
            options: {
                files:      [ 'client/**/*.spec.js' ],
                frameworks: [ 'jasmine'   ],
                reporters:  [ 'progress'  ],
                browsers:   [ 'PhantomJS' ],
                singleRun:  true,
                autoWatch:  false
            },
            continuous: {
                singleRun:  false,
                background: true
            }
        },

        concat: { ... },

        uglify: { ... },

        watch: {
            startup: {
                files: [], // This is redundant, but we get an error if not specifying files.
                tasks: [ 'karma:continuous:start' ],
                options: {
                    atBegin: true,
                    spawn: false
                }
            },

            js: {
                files: [ '<%= concat.js.src %>' ],
                tasks: [ 'concat:js', 'uglify' ]
            },

            karma: {
                files: [ '<%= concat.js.src %>', 'src/**/test/**/*.js' ],
                tasks: [ 'karma:continuous:run' ]
            },

        }
    });

    require('load-grunt-tasks')(grunt);

    grunt.registerTask( 'default', [ 'concat', 'uglify', 'karma:unit:run' ] );
};

Option #2

As shown in this and this blogs, an alternative is instead of calling

$ grunt watch

one creates another task that launch the karma server:

grunt.registerTask( 'serve', [ 'karma:continuous:start', 'watch' ] );

and then calls:

$ grunt serve

The full Gruntfile.js:

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        karma: {
            options: {
                configFile: 'karma.conf.js'
            },
            unit: {
                singleRun: true
            },
            continuous: {
                // keep karma running in the background
                background: true
            }
        },

        concat: { ... },

        uglify: { ... },

        watch: {   
            js: {
                files: [ '<%= concat.js.src %>' ],
                tasks: [ 'concat:js', 'uglify' ]
            },

            karma: {
                files: [ '<%= concat.js.src %>', 'src/**/test/**/*.js' ],
                tasks: [ 'karma:continuous:run' ]
            },

        }
    });

    require('load-grunt-tasks')(grunt);

    grunt.registerTask( 'default', [ 'concat', 'uglify', 'karma:unit:run' ] );

    grunt.registerTask( 'serve', [ 'karma:continuous:start', 'watch' ] );
};

Upvotes: 6

Related Questions