grunt-karma is a Grunt plugin that integrates the Karma test runner into Grunt build workflows. It enables developers to configure and execute JavaScript unit tests through Grunt tasks with support for multiple testing configurations, background test server modes, and continuous integration setups.
npm install grunt-karma --save-devgrunt >= 0.4.x, karma ^4.0.0 || ^5.0.0 || ^6.0.0This plugin is loaded through Grunt's plugin system:
grunt.loadNpmTasks('grunt-karma');Add a karma task configuration to your Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
karma: {
unit: {
configFile: 'karma.conf.js'
}
}
});
grunt.loadNpmTasks('grunt-karma');
// Run tests
grunt.registerTask('test', ['karma:unit']);
};Run tests with:
grunt karma:unitgrunt-karma provides a single Grunt multi-task that interfaces with Karma's API:
karma multi-task that supports various execution modesThe main karma multi-task with flexible configuration options.
/**
* Grunt multi-task for running Karma test runner
* Task name: 'karma'
* Task description: 'run karma.'
*/Task Configuration Options:
interface KarmaTaskConfig {
/** Run karma in background child process mode (default: false) */
background?: boolean;
/** Client configuration passed to karma */
client?: {
/** Command line arguments passed to test frameworks */
args?: string[];
};
/** Path to karma configuration file */
configFile?: string;
/** Array of file patterns to include in testing */
files?: Array<string | FileObject>;
/** Array of browsers to run tests in */
browsers?: string[];
/** Port number for karma server */
port?: number;
/** Run tests once and exit */
singleRun?: boolean;
/** Watch files and re-run tests on changes */
autoWatch?: boolean;
/** Logging level: 'OFF' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' */
logLevel?: string;
/** Preprocessor configuration for files */
preprocessors?: Record<string, string[]>;
/** Base path for resolving file patterns */
basePath?: string;
/** Test frameworks to use (e.g., 'mocha', 'jasmine') */
frameworks?: string[];
/** Karma plugins to load */
plugins?: string[];
/** Test result reporters ('progress', 'dots', 'junit', etc.) */
reporters?: string | string[];
}
interface FileObject {
/** File pattern */
pattern: string;
/** Whether to watch file for changes */
watched?: boolean;
/** Whether to serve file via karma web server */
served?: boolean;
/** Whether to include file in test runner */
included?: boolean;
}Usage Examples:
Basic configuration with external karma.conf.js:
karma: {
unit: {
configFile: 'karma.conf.js'
}
}Inline configuration:
karma: {
unit: {
options: {
files: ['src/**/*.js', 'test/**/*.spec.js'],
browsers: ['Chrome'],
singleRun: true,
logLevel: 'INFO'
}
}
}Multiple targets with shared options:
karma: {
options: {
configFile: 'karma.conf.js',
browsers: ['Chrome', 'Firefox']
},
continuous: {
singleRun: true,
browsers: ['PhantomJS']
},
dev: {
autoWatch: true,
singleRun: false
}
}Run Karma server in a child process to avoid blocking subsequent Grunt tasks.
/**
* Background mode configuration
* Enables running karma server in child process
*/
interface BackgroundModeConfig {
background: true;
singleRun: false;
}Usage Example:
karma: {
unit: {
configFile: 'karma.conf.js',
background: true,
singleRun: false
}
}
watch: {
karma: {
files: ['src/**/*.js', 'test/**/*.js'],
tasks: ['karma:unit:run'] // Note: :run flag
}
}Start background server and watch:
grunt karma:unit:start watchConnect to an existing Karma server to trigger test runs, useful with grunt-contrib-watch.
Usage:
grunt karma:unit:runThis connects to an already running Karma server (started with karma:unit:start) and triggers a test run.
Grunt-style file configuration with additional Karma-specific options.
/**
* Grunt file configuration extended with Karma options
*/
interface GruntKarmaFiles {
files: Array<{
src: string[];
/** Whether to watch file for changes */
watched?: boolean;
/** Whether to serve file via karma web server */
served?: boolean;
/** Whether to include file in test runner */
included?: boolean;
}>;
}Usage Example:
karma: {
unit: {
files: [
{ src: ['src/**/*.js'], served: true, included: false },
{ src: ['test/**/*.spec.js'], served: true, included: true }
]
}
}File Processing Behavior:
options.files are processed first, then this.filessrc pattern becomes a separate file entrywatched, served, included) are copied from file object to individual entriesSupports Grunt template strings in file patterns and preprocessor configurations. Results are flattened, so arrays are expanded before passing to Karma.
Usage Example:
meta: {
jsFiles: ['jquery.js', 'angular.js']
},
karma: {
options: {
files: ['<%= meta.jsFiles %>', 'angular-mocks.js', '**/*-spec.js'],
preprocessors: {
'<%= basePath %>/src/**/*.js': ['coverage']
}
}
}Template Processing Features:
Pass command line arguments to test frameworks via client.args.
Usage:
grunt karma:dev --grep=mypatternArguments starting with -- or - are automatically passed to client.args.
Argument Processing:
process.argv.slice(2)/^--?/ pattern are includedclient.args if presentclient.args are concatenated with option-level client.argsMerge Priority (highest to lowest):
this.data)this.options()){ background: false, client: {} })Special Merge Behavior:
browsers array: Task data completely overrides options (no merging)client.args array: Task data is concatenated with options datafiles array: Options files processed first, then task files (both included)Standard Mode (Default):
grunt karma:unitBackground Mode:
background: true in config, then grunt karma:unit:startRun Mode:
grunt karma:unit:run (after server is started)Single Run Mode:
singleRun: true in configWatch Mode:
autoWatch: true in configkarma: {
ci: {
configFile: 'karma.conf.js',
singleRun: true,
browsers: ['PhantomJS']
}
}karma: {
dev: {
configFile: 'karma.conf.js',
autoWatch: true,
singleRun: false
}
}karma: {
unit: {
configFile: 'karma.conf.js',
background: true,
singleRun: false
}
},
watch: {
karma: {
files: ['src/**/*.js', 'test/**/*.js'],
tasks: ['karma:unit:run']
}
}Start with: grunt karma:unit:start watch
When using background mode, the child process may exit with errors:
// Background process error handling is automatic
// Errors are logged as: "background karma process exited with error (code: X)"
// Process cleanup occurs automatically on parent process exitTasks complete based on Karma exit codes:
Runtime Dependencies:
lodash ^4.17.10: Used for data manipulation and configuration mergingIntegration:
karma: {
options: {
configFile: 'karma.conf.js'
},
unit: {
browsers: ['Chrome']
},
integration: {
configFile: 'karma.integration.conf.js',
browsers: ['Chrome', 'Firefox']
},
ci: {
singleRun: true,
browsers: ['PhantomJS']
}
}Nested Array Flattening:
karma: {
flatten: {
options: {
files: [
[['node_modules/expect.js/index.js']],
[[['test/**/*.js']]]
]
},
singleRun: true
}
}Files arrays are automatically flattened at any nesting level before being passed to Karma.
File Merging Priority:
karma: {
options: {
files: ['lib/**/*.js'] // These come first
},
merge: {
options: {
files: ['node_modules/expect.js/index.js'] // Then these
},
files: [
{ src: 'test/**/*.js' } // Finally task-level files
]
}
}Karma 6.x Support: grunt-karma v4.0.2 includes enhanced support for Karma 6.x with automatic detection of the parseConfig API:
// The plugin automatically handles different Karma versions:
// - Karma 6+: Uses parseConfig with promiseConfig: true
// - Karma < 6: Uses legacy parseConfig APIparseConfig Pattern (Internal):
// For Karma 6+
var parsedConfig = parseConfig(
data.configFile,
data,
{promiseConfig: true, throwErrors: true}
);
// Supports both promise-based and legacy callback patterns
if (parsedConfig.then) {
parsedConfig.then(function (config) {
var server = new Server(config, finished.bind(done));
server.start();
});
} else {
// Legacy support for Karma < 6
var server = new Server(data, finished.bind(done));
server.start();
}Complete Development Workflow:
karma: {
options: {
browsers: ['Chrome'],
frameworks: ['mocha'],
plugins: ['karma-mocha', 'karma-chrome-launcher']
},
single: {
singleRun: true,
files: [
{ src: 'node_modules/expect.js/index.js' },
{ src: 'test/**/*.js' }
]
},
background: {
background: true,
files: [
{ src: 'node_modules/expect.js/index.js' },
{ src: 'test/**/*.js' }
]
},
dev: {
reporters: 'dots',
background: true
}
},
watch: {
tests: {
files: 'test/**/*.js',
tasks: ['karma:dev:run']
}
}Environment-Specific Configuration:
module.exports = function (grunt) {
var browsers = process.env.TRAVIS ? ['Firefox'] : ['Chrome'];
var plugins = ['karma-mocha'].concat(
process.env.TRAVIS ? ['karma-firefox-launcher'] : ['karma-chrome-launcher']
);
grunt.initConfig({
karma: {
options: {
browsers: browsers,
frameworks: ['mocha'],
plugins: plugins
},
test: {
singleRun: true,
files: ['test/**/*.js']
}
}
});
};Task Registration Patterns:
// Individual test tasks
grunt.registerTask('test:unit', ['karma:single']);
grunt.registerTask('test:config', ['karma:config']);
grunt.registerTask('test:merge', ['karma:merge']);
// Comprehensive test suite
grunt.registerTask('test', [
'eslint',
'karma:single',
'karma:config',
'karma:merge',
'karma:flatten'
]);
// Background testing workflow
grunt.registerTask('bgtest', ['karma:background', 'watch:bgtest']);