or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-grunt-karma

Grunt plugin for integrating Karma test runner into build workflows

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/grunt-karma@4.0.x

To install, run

npx @tessl/cli install tessl/npm-grunt-karma@4.0.0

index.mddocs/

grunt-karma

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.

Package Information

  • Package Name: grunt-karma
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install grunt-karma --save-dev
  • Peer Dependencies: grunt >= 0.4.x, karma ^4.0.0 || ^5.0.0 || ^6.0.0

Core Imports

This plugin is loaded through Grunt's plugin system:

grunt.loadNpmTasks('grunt-karma');

Basic Usage

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:unit

Architecture

grunt-karma provides a single Grunt multi-task that interfaces with Karma's API:

  • Main Task: karma multi-task that supports various execution modes
  • Background Mode: Runs Karma server in child process for watch workflows
  • Run Mode: Connects to existing Karma server to trigger test runs
  • Configuration Merging: Combines Grunt task options with Karma configuration files

Capabilities

Karma Task Configuration

The 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
  }
}

Background Mode

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 watch

Run Mode

Connect to an existing Karma server to trigger test runs, useful with grunt-contrib-watch.

Usage:

grunt karma:unit:run

This connects to an already running Karma server (started with karma:unit:start) and triggers a test run.

File Configuration

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:

  • Files from options.files are processed first, then this.files
  • Nested arrays in file patterns are automatically flattened
  • File objects are expanded: each src pattern becomes a separate file entry
  • Properties (watched, served, included) are copied from file object to individual entries
  • Grunt file expansion produces exactly 2-level deep structure that is processed appropriately

Template String Support

Supports 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:

  • File arrays are automatically flattened
  • Preprocessor keys are resolved with basePath and processed through grunt.template.process()
  • Path resolution converts relative paths to absolute paths

Command Line Arguments

Pass command line arguments to test frameworks via client.args.

Usage:

grunt karma:dev --grep=mypattern

Arguments starting with -- or - are automatically passed to client.args.

Argument Processing:

  • CLI arguments are parsed from process.argv.slice(2)
  • Only arguments matching /^--?/ pattern are included
  • Arguments are merged with existing client.args if present
  • Task-specific client.args are concatenated with option-level client.args

Configuration Merging

Merge Priority (highest to lowest):

  1. Task-specific data (this.data)
  2. Task options (this.options())
  3. Default 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 data
  • files array: Options files processed first, then task files (both included)
  • Other properties: Standard lodash deep merge behavior

Task Execution Modes

Standard Mode (Default):

  • Runs Karma server in main process
  • Blocks until tests complete
  • Usage: grunt karma:unit

Background Mode:

  • Runs Karma server in child process
  • Doesn't block subsequent tasks
  • Usage: Set background: true in config, then grunt karma:unit:start

Run Mode:

  • Connects to existing Karma server
  • Triggers test run on running server
  • Usage: grunt karma:unit:run (after server is started)

Single Run Mode:

  • Runs tests once and exits
  • Ideal for CI/build processes
  • Usage: Set singleRun: true in config

Watch Mode:

  • Keeps server running and watches files
  • Re-runs tests on file changes
  • Usage: Set autoWatch: true in config

Common Usage Patterns

Continuous Integration

karma: {
  ci: {
    configFile: 'karma.conf.js',
    singleRun: true,
    browsers: ['PhantomJS']
  }
}

Development with Watch

karma: {
  dev: {
    configFile: 'karma.conf.js',
    autoWatch: true,
    singleRun: false
  }
}

Background Testing with Grunt Watch

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

Error Handling

Background Process Errors

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 exit

Task Completion

Tasks complete based on Karma exit codes:

  • Exit code 0: Task succeeds
  • Non-zero exit code: Task fails

Dependencies

Runtime Dependencies:

  • lodash ^4.17.10: Used for data manipulation and configuration merging

Integration:

  • Requires Node.js child_process module for background mode
  • Uses path module for file resolution
  • Integrates with Karma's Server, runner, and config.parseConfig APIs

Multiple Configurations

karma: {
  options: {
    configFile: 'karma.conf.js'
  },
  unit: {
    browsers: ['Chrome']
  },
  integration: {
    configFile: 'karma.integration.conf.js',
    browsers: ['Chrome', 'Firefox']
  },
  ci: {
    singleRun: true,
    browsers: ['PhantomJS']
  }
}

Advanced File Array Patterns

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 Version Compatibility

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 API

parseConfig 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();
}

Real-World Usage Examples

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']);