Technical Documentation: karma-runner/karma
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (`README.md`)
Karma
A simple tool that allows you to execute JavaScript code in multiple
real browsers.
The main purpose of Karma is to make your test-driven development easy,
fast, and fun.
Karma is deprecated and is not accepting new features or general bug fixes.
The web testing space has evolved significantly in the 10+ years since Karma's creation. The web landscape looks very different today and new patterns and tools have emerged in the ecosystem. New test runners offer more performant alternatives, and Karma no longer provides clear unique value.
Based on the current state of the web testing ecosystem, we have made the hard decision to deprecate Karma.
We know Karma is used particularly commonly in the Angular ecosystem, so Angular is adding Jest and Web Test Runner support to provide a migration path off of Karma. See the Angular blog for more details.
Critical security issues in Karma will still be triaged and fixed as necessary. This will continue until 12 months after Angular CLI's Web Test Runner support is marked stable.
For those outside Angular looking to migrate off Karma, both Web Test Runner and jasmine-browser-runner provide browser-based unit testing solutions which can be used as a direct alternative. Jest and Vitest also provide Node-based alternatives.
It has been incredible to see Karma's impact on the web testing ecosystem and we greatly appreciate the support of everyone who contributed to an awesome community. Keep testing. ✅
Help and Support
For questions and support please use the mailing list or Gitter.
The issue tracker is for bug reports and feature discussions only.
- Obligatory documentation
- Quick questions:
- Longer questions: Mailing List
- Bug reports Issue Tracker
- Everything less than 140 characters: @JsKarma on Twitter
When should I use Karma?
- You want to test code in real browsers.
- You want to test code in multiple browsers (desktop, mobile,
tablets, etc.). - You want to execute your tests locally during development.
- You want to execute your tests on a continuous integration server.
- You want to execute your tests on every save.
- You love your terminal.
- You don't want your (testing) life to suck.
- You want to use Istanbul to automagically generate coverage
reports. - You want to use RequireJS for your source files.
But I still want to use \_insert testing library\_
Karma is not a testing framework, nor an assertion library.
Karma just launches an HTTP server, and generates the test runner HTML file you probably already know from your favourite testing framework.
So for testing purposes you can use pretty much anything you like. There are already plugins for most of the common testing frameworks:
- Jasmine
- Mocha
- QUnit
- and many others
If you can't find an adapter for your favourite framework, don't worry and write your own.
It's not that hard and we are here to help.
Which Browsers can I use?
All the major browsers are supported, if you want to know more see the
browsers page.
Troubleshooting
See FAQ.
I want to use it. Where do I sign?
You don't need to sign anything but here are some resources to help
you to get started...
Obligatory Screencast.
Every serious project has a screencast, so here is ours. Just click
here and let the show begin.
Installation.
See installation.
Using it.
See configuration.
This is so great. I want to help.
Please, see
contributing.
Why did you create this?
Throughout the development of AngularJS, we've been using JSTD for
testing. I really think that JSTD is a great idea. Unfortunately, we
had many problems with JSTD, so we decided to write our own test
runner based on the same idea. We wanted a simple tool just for
executing JavaScript tests that is both stable and fast. That's why we
use the awesome Socket.io library and Node.js.
My boss wants a license. So where is it?
Index (`docs/index.md`)
layout: homepage pageTitle: Spectacular Test Runner for Javascript
About 01 Versioning (`docs/about/01-versioning.md`)
Karma uses Semantic Versioning.
It is recommended that you add Karma by running:
$ yarn add --dev karmaor:
$ npm --save-dev install karmaAbout 03 Migration (`docs/about/03-migration.md`)
pageTitle: Migration from v0.10
The good thing is that you don't have to migrate everything at once.
You can leave all the existing projects using an older version of Karma and only use the latest
version for the new projects. Alternatively, you can migrate the existing projects one at a time...
Anyway, this migration should be easy ;-) so let's get started...
cd <path-to-your-project>
npm install karma --save-devThis will install the latest version of Karma and also update package.json of your project.
Install missing plugins
Karma does not ship with any "default" plugins anymore.
For existing projects, this should not cause any problems as npm (when updating Karma to 0.10 usingnpm install karma --save-dev) added these "default" plugins into package.json as regular dependencies.
For new projects, just remember you have to install all the plugins you need. These are the "default" plugins that were removed:
- karma-jasmine
- karma-requirejs
- karma-coffee-preprocessor
- karma-html2js-preprocessor
- karma-chrome-launcher
- karma-firefox-launcher
- karma-phantomjs-launcher
- karma-script-launcher
Install CLI interface
Karma does not put the karma command in your system PATH anymore.
If you want to use the karma command, please install the command line interface (karma-cli).
You probably have the karma package installed globally, in which case you should remove it first:
npm remove -g karmaAnd then install the command line interface:
npm install karma-cliDefault configuration
autoWatch is true by default, so if you don't wanna use it make sure you set it to false.
But hey, give it a shot first, it's really awesome to run your tests on every save!
npm complaining
In some cases, npm can run into dependency tree issues during the migration process. If you are faced with an "unsatisfied peer dependency" error, removing all of the packages (rm -rf ./node_modules) and installing them again should clear up the issue.
If you have any other issues, please ask on the mailing list.
Config 01 Configuration File (`docs/config/01-configuration-file.md`)
Overview
In order to serve you well, Karma needs to know about your project in order to test it
and this is done via a configuration file. The easiest way to generate an initial configuration file
is by using the karma init command. This page lists all of the available configuration options.
Note: Most of the framework adapters, reporters, preprocessors and launchers need to be loaded as plugins.
The Karma configuration file can be written in JavaScript, CoffeeScript, or TypeScript and is loaded as a regular Node.js module.
Unless provided as argument, the Karma CLI will look for a configuration file at
./karma.conf.js./karma.conf.coffee./karma.conf.ts./.config/karma.conf.js./.config/karma.conf.coffee./.config/karma.conf.ts
in that order.
Within the configuration file, the configuration code is put together by setting module.exports to point to a function
which accepts one argument: the configuration object.
// karma.conf.js
module.exports = function(config) {
config.set({
basePath: '../..',
frameworks: ['jasmine'],
//...
});
};# karma.conf.coffee
module.exports = (config) ->
config.set
basePath: '../..'
frameworks: ['jasmine']
# ...// karma.conf.ts
module.exports = (config) => {
config.set({
basePath: '../..',
frameworks: ['jasmine'],
//...
});
}Alternatively, you can use an async function instead (since v6.3).
// karma.conf.js
module.exports = async (config) => {
const karmaConfig = await getKarmaConfig("dev");
config.set({
...karmaConfig
});
};Customized TypeScript Configuration
Under the hood Karma uses ts-node to transpile TypeScript to JavaScript. If the resolved tsconfig.json has module configured as ES formats. You might get errors like SyntaxError: Unexpected token. This is due that in Node ES module formats are not supported. To overcome this issue you need to configure ts-node to use commonjs module format.
Create a JavaScript configuration file that overrides the module format.
// karma.conf.js
require('ts-node').register({
compilerOptions: {
module: 'commonjs'
}
});
require('./karma.conf.ts');File Patterns
All of the configuration options, which specify file paths, use the minimatch library to facilitate flexible
but concise file expressions so you can easily list all of the files you want to include and exclude.
You can find details about each configuration option in the section below. The following options utilize minimatch expressions:
excludefilespreprocessors
Examples:
**/*.js: All files with a "js" extension in all subdirectories**/!(jquery).js: Same as previous, but excludes "jquery.js"**/(foo|bar).js: In all subdirectories, all "foo.js" or "bar.js" files
Configuration Options
These are all of the available configuration options.
autoWatch
Type: Boolean
Default: true
CLI: --auto-watch, --no-auto-watch
Description: Enable or disable watching files and executing the tests whenever one of these files changes.
autoWatchBatchDelay
Type: Number
Default: 250
Description: When Karma is watching the files for changes, it tries to batch
multiple changes into a single run so that the test runner doesn't try to start and restart running
tests more than it should, or restart while build files are not in a consistent state. The configuration setting
tells Karma how long to wait (in milliseconds) from the last file change before starting
the test process again, resetting the timer each time a file changes (i.e. debouncing).
basePath
Type: String
Default: ''
Description: The root path location that will be used to resolve all relative
paths defined in files and exclude. If the basePath configuration is a
relative path, then it will be resolved to the __dirname of the configuration file.
browserDisconnectTimeout
Type: Number
Default: 2000
Description: How long does Karma wait for a browser to reconnect (in ms).
With a flaky connection, it is pretty common that the browser disconnects, but the actual test execution is still running
without any problems. Karma does not treat a disconnection as an immediate failure and will wait for browserDisconnectTimeout (ms).
If the browser reconnects during that time, everything is fine.
browserConsoleLogOptions
Type: Object
Default: {level: "debug", format: "%b %T: %m", terminal: true}
Description: Configure how the browser console is logged with the following
properties, all of which are optional:
{
level: string,
format: string,
path: string,
terminal: boolean
}Here the level is the desired log-level, where level log always is logged. The format
is a string where %b, %t, %T, and %m are replaced with the browser string,
log type in lower-case, log type in uppercase, and log message, respectively. This format will
only effect the output file. path is the output-path of the output-file, and terminal indicates
if the log should be written in the terminal, or not.
browserDisconnectTolerance
Type: Number
Default: 0
Description: The number of disconnections tolerated.
The disconnectTolerance value represents the maximum number of tries a browser will attempt in the case of a disconnection.
Usually, any disconnection is considered a failure, but this option allows you to define a tolerance level when there is
a flaky network link between the Karma server and the browsers.
browserNoActivityTimeout
Type: Number
Default: 30000
Description: How long will Karma wait for a message from a browser before disconnecting from it (in ms).
If, during test execution, Karma does not receive any message from a browser within browserNoActivityTimeout(ms), it will disconnect from the browser. The default is the one recommended by Travis (https://docs.travis-ci.com/user/gui-and-headless-browsers/#karma-and-firefox-inactivity-timeouts)
browsers
Type: Array
Default: []
CLI: --browsers Chrome,Firefox, --no-browsers
Possible Values:
Chrome(launcher requires karma-chrome-launcher plugin)ChromeCanary(launcher requires karma-chrome-launcher plugin)ChromeHeadless(launcher requires karma-chrome-launcher plugin ^2.1.0)PhantomJS(launcher requires karma-phantomjs-launcher plugin)Firefox(launcher requires karma-firefox-launcher plugin)Opera(launcher requires karma-opera-launcher plugin)IE(launcher requires karma-ie-launcher plugin)Safari(launcher requires karma-safari-launcher plugin)
Description: A list of browsers to launch and capture. When Karma starts up, it will also start up each browser
which is placed within this setting. Once Karma is shut down, it will shut down these
browsers as well. You can capture any browser manually by opening the browser and visiting the URL where
the Karma web server is listening (by default it is http://localhost:9876/).
See config/browsers for more information. Additional launchers can be defined through plugins. Use the--no-browsers command line option to override the value of this setting specified in the configuration file
with an empty list.
captureTimeout
Type: Number
Default: 60000
Description: Timeout for capturing a browser (in ms).
The captureTimeout value represents the maximum boot-up time allowed for a browser to start and connect to Karma.
If any browser does not get captured within the timeout, Karma will kill it and try to launch
it again and, after three attempts to capture it, Karma will give up.
client.args
Type: Array
Default: undefined
CLI: All arguments after -- (only when using karma run)
Description: When karma run is passed additional arguments on the command-line, they
are passed through to the test adapter as karma.config.args (an array of strings).
The client.args option allows you to set this value for actions other than run.
How this value is used is up to your test adapter - you should check your adapter's documentation to see how (and if) it uses this value.
client.useIframe
Type: Boolean
Default: true
Description: Run the tests inside an iFrame or a new window
If true, Karma runs the tests inside an iFrame. If false, Karma runs the tests in a new window. Some tests may not run in an
iFrame and may need a new window to run.
client.runInParent
Type: Boolean
Default: false
Description: Run the tests on the same window as the client, without using iframe or a new window
If true, Karma runs the tests inside the original window without using iframe. It will load the test scripts dynamically.
client.captureConsole
Type: Boolean
Default: true
Description: Capture all console output and pipe it to the terminal.
client.clearContext
Type: Boolean
Default: true
Description: Clear the context window
If true, Karma clears the context window upon the completion of running the tests. If false, Karma does not clear the context window
upon the completion of running the tests. Setting this to false is useful when embedding a Jasmine Spec Runner Template.
client.clientDisplayNone
Type: Boolean
Default: false
Description: Set style display none on client elements.
If true, Karma does not display the banner and browser list. Useful when using karma on component tests with screenshots.
client.allowedReturnUrlPatterns
Type: Array
Default: ['^https?://']
Description: Define the string representations of the regular expressions that will be allowed for the return_url query parameter.
If the value of the return_url query parameter does not match any regular expression derived from the string representation of each of the elements of this array, navigation to it will be blocked.
colors
Type: Boolean
Default: true
CLI: --colors, --no-colors
Description: Enable or disable colors in the output (reporters and logs).
concurrency
Type: Number
Default: Infinity
Description: How many browsers Karma launches in parallel.
Especially on services like SauceLabs and Browserstack, it makes sense only to launch a limited amount of browsers at once, and only start more when those have finished. Using this configuration, you can specify how many browsers should be running at once at any given point in time.
crossOriginAttribute
Type: Boolean
Default: true
Description: When true, this will append the crossorigin attribute to generated script tags, which enables better error reporting for JavaScript files served from a different origin.
Disable this when you need to load external scripts that are served without the necessary Access-Control-Allow-Origin header.
customContextFile
Type: string
Default: null
Description: If null (default), uses karma's own context.html file.
customDebugFile
Type: string
Default: null
Description: If null (default), uses karma's own debug.html file.
customClientContextFile
Type: string
Default: null
Description: If null (default), uses karma's own client_with_context.html file (which is used when client.runInParent set to true).
customHeaders
Type: Array
Default: undefined
Description Custom HTTP headers that will be set upon serving files by Karma's web server.
Custom headers are useful, especially with upcoming browser features like Service Workers.
The customHeaders option allows you to set HTTP headers for files that match a regular expression.customHeaders is an array of Objects with properties as follows:
- match: Regular expression string to match files
- name: HTTP header name
- value: HTTP header value
Example:
customHeaders: [{
match: '.*foo.html',
name: 'Service-Worker-Allowed',
value: '/'
}]detached
Type: Boolean
Default: false
CLI: --detached
Description: When true, this will start the karma server in another process, writing no output to the console.
The server can be stopped using the karma stop command.
exclude
Type: Array
Default: []
Description: List of files/patterns to exclude from loaded files.
failOnEmptyTestSuite
Type: Boolean
Default: true
CLI: --fail-on-empty-test-suite, --no-fail-on-empty-test-suite
Description: Enable or disable failure on running empty test-suites. If disabled the program
will return exit-code 0 and display a warning.
failOnSkippedTests
Type: Boolean
Default: false
CLI: --fail-on-skipped-tests, --no-fail-on-skipped-tests
Description: Enable or disable failure on tests deliberately disabled, eg fit() or xit() tests in jasmine.
Use this to prevent accidental disabling tests needed to validate production.
failOnFailingTestSuite
Type: Boolean
Default: true
CLI: --fail-on-failing-test-suite, --no-fail-on-failing-test-suite
Description: Enable or disable failure on failing tests.
files
Type: Array
Default: []
Description: List of files/patterns to load in the browser.
See config/files for more information.
forceJSONP
Type: Boolean
Default: false
Description: Force socket.io to use JSONP polling instead of XHR polling.
frameworks
Type: Array
Default: []
Description: List of test frameworks you want to use. Typically, you will set this to ['jasmine'], ['mocha'] or ['qunit']...
Please note just about all frameworks in Karma require an additional plugin/framework library to be installed (via npm).
Additional information can be found in plugins.
listenAddress
Type: String
Default: '0.0.0.0' or LISTEN_ADDR
Description: Address that the server will listen on. Change to 'localhost' to only listen to the loopback, or '::' to listen on all IPv6 interfaces
hostname
Type: String
Default: 'localhost'
Description: Hostname to be used when capturing browsers.
httpsServerOptions
Type: Object
Default: {}
Description: Options object to be used by Node's https class.
Object description can be found in the NodeJS.org API docs
Example:
httpsServerOptions: {
key: fs.readFileSync('server.key', 'utf8'),
cert: fs.readFileSync('server.crt', 'utf8')
},logLevel
Type: Constant
Default: config.LOG_INFO
CLI: --log-level debug
Possible values:
config.LOG_DISABLEconfig.LOG_ERRORconfig.LOG_WARNconfig.LOG_INFOconfig.LOG_DEBUG
Description: Level of logging.
loggers
Type: Array
Default: [{type: 'console'}]
Description: A list of log appenders to be used. See the documentation for log4js for more information.
middleware
Type: Array
Default: []
Description: List of names of additional middleware you want the karma server to use. Middleware will be used in the order listed.
You must have installed the middleware via a plugin/framework (either inline or via npm). Additional information can be found in plugins.
The plugin must provide an express/connect middleware function (details about this can be found in the Express docs. An example of custom inline middleware is shown below.
Example:
function CustomMiddlewareFactory (config) {
return function (request, response, /* next */) {
response.writeHead(200)
return response.end("content!")
}
}middleware: ['custom']
plugins: [
{'middleware:custom': ['factory', CustomMiddlewareFactory]}
...
]mime
Type: Object
Default: {}
Description: Redefine default mapping from file extensions to MIME-type
Set property name to required MIME, provide Array of extensions (without dots) as it's value
Example:
mime: {
'text/x-typescript': ['ts','tsx']
'text/plain' : ['mytxt']
}beforeMiddleware
Type: Array
Default: []
Description: This is the same as middleware except that these middleware will be run before karma's own middleware.
plugins
Type: Array
Default: ['karma-*']
Description: List of plugins to load. A plugin can be either a plugin object, or a string containing name of the module which exports a plugin object. See plugins for more information on how to install and use plugins.
By default, Karma loads plugins from all sibling npm packages which have a name starting with karma-*.
port
Type: Number
Default: 9876
CLI: --port 9876
Description: The port where the web server will be listening.
If the defined port is already in use, karma will automatically increase its value in steps of 1 until a free port is found.
processKillTimeout
Type: Number
Default: 2000
Description: How long will Karma wait for browser process to terminate before sending a SIGKILL signal.
If, after test execution or after Karma attempts to kill the browser, browser is not killed within processKillTimeout(ms), Karma will send a SIGKILL signal to attempt to kill the browser forcefully.
preprocessors
Type: Object
Default: {'**/*.coffee': 'coffee'}
Description: A map of preprocessors to use.
Preprocessors can be loaded through plugins.
Note: Just about all preprocessors in Karma require an additional library to be installed (via npm).
Be aware that preprocessors may be transforming the files and file types that are available at run time. For instance,
if you are using the "coverage" preprocessor on your source files, if you then attempt to interactively debug
your tests, you'll discover that your expected source code is completely changed from what you expected. Because
of that, you'll want to engineer this so that your automated builds use the coverage entry in the "reporters" list,
but your interactive debugging does not.
Click here for more information.
protocol
Type: String
Default: 'http:'
Possible Values:
http:https:
Description: Protocol used for running the Karma webserver.
Determines the use of the Node http or https class.
Note: Using 'https:' requires you to specify httpsServerOptions.
httpModule
Type: String
Default: undefined
Description: Module used for Karma webserver.
Uses the provided module instead of node's built in http or https module. The module loaded here must exactly match the interface of node's http module. This can be useful for loading in a module like node-http2 to allow for http2 support.
Note: if you're using this to enable http2 you must also set the protocol to https: and specify certificates as http2 can only run of https.
proxies
Type: Object
Default: {}
Description: A map of path-proxy pairs.
The proxy can be specified directly by the target url or path, or with an object to configure more options. The available options are:
targetThe target url or path (mandatory)changeOriginWhether or not the proxy should override the Host header using the host from the target (defaultfalse)
Example:
proxies: {
'/static': 'http://gstatic.com',
'/web': 'http://localhost:9000',
'/img/': '/base/test/images/',
'/proxyfied': {
'target': 'http://myserver.localhost',
'changeOrigin': true
}
},proxyValidateSSL
Type: Boolean
Default: true
Description: Whether or not Karma or any browsers should raise an error when an invalid SSL certificate is found.
reportSlowerThan
Type: Number
Default: 0
Description: Karma will report all the tests that are slower than given time limit (in ms).
This is disabled by default (since the default value is 0).
reporters
Type: Array
Default: ['progress']
CLI: --reporters progress,growl
Possible Values:
dotsprogress
Description: A list of reporters to use.
Additional reporters, such as growl, junit, teamcity or coverage can be loaded through plugins.
Note: Just about all additional reporters in Karma (other than progress) require an additional library to be installed (via npm).
formatError
Type: Function
Default: undefined
CLI: --format-error ./path/to/formatFunction.js
Arguments:
msg- A single line of the assertion error and stack trace (called for each line).
Returns: A new error message line.
Description: Format assertion errors and stack traces. Useful for removing vendors and compiled sources. Return an empty line '' to remove it.
The CLI option should be a path to a file that exports the format function. This can be a function exported at the root of the module or an export named formatError.
pingTimeout
Type Number
Default 5000
Description Socket.io pingTimeout in ms, https://socket.io/docs/server-api/#new-Server-httpServer-options.
Very slow networks may need values up to 60000. Larger values delay discovery of deadlock in tests or browser crashes.
restartOnFileChange
Type: Boolean
Default: false
Description: When Karma is watching the files for changes, it will delay a new run until
the current run is finished. Enabling this setting will cancel the current run and start a new run
immediately when a change is detected.
retryLimit
Type: Number
Default: 2
Description: When a browser crashes, karma will try to relaunch. This defines how many times karma should relaunch
a browser before giving up.
singleRun
Type: Boolean
Default: false
CLI: --single-run, --no-single-run
Description: Continuous Integration mode.
If true, Karma will start and capture all configured browsers, run tests and then exit with an exit code of 0 or 1 depending
on whether all tests passed or any tests failed.
transports
Type: Array
Default: ['polling', 'websocket']
Description: An array of allowed transport methods between the browser and testing server. This configuration setting
is handed off to socket.io (which manages the communication
between browsers and the testing server).
proxyReq
Type: Function
Default: undefined
Description: Called when requesting Proxy.
Details about this can be found in the node-http-proxy. An example of overwriting the HTTP header is shown below.
Example:
proxyReq: function(proxyReq, req, res, options) {
proxyReq.setHeader('Referer', 'https://www.example.com/');
}proxyRes
Type: Function
Default: undefined
Description: Called when respnsing Proxy.
Details about this can be found in the node-http-proxy. An example of overwriting the HTTP header is shown below.
Example:
proxyRes: function(proxyRes, req, res) {
if (proxyRes.headers['set-cookie']) {
proxyRes.headers['set-cookie'] = proxyRes.headers['set-cookie'].map(function (cookie) {
return cookie.replace(/\s*secure;?/i, '');
})
}
}upstreamProxy
Type: Object
Default: undefined
Description: For use when the Karma server needs to be run behind a proxy that changes the base url, etc
If set then the following fields will be defined and can be overridden:
path
Type: String
Default: '/'
Description: Will be prepended to the base url when launching browsers and prepended to internal urls as loaded by the browsers
port
Type: Number
Default: 9875
Description: Will be used as the port when launching browsers
hostname
Type: String
Default: 'localhost'
Description: Will be used as the hostname when launching browsers
protocol
Type: String
Default: 'http:'
Description: Will be used as the protocol when launching browsers
urlRoot
Type: String
Default: '/'
Description: The base url, where Karma runs.
All of Karma's urls get prefixed with the urlRoot. This is helpful when using proxies, as
sometimes you might want to proxy a url that is already taken by Karma.
browserSocketTimeout
Type: Number
Default: 20000
Description: Timeout for the client socket connection (in ms).
This configuration represents the amount of time that the client will wait for the socket
to connect.
When running a browser in different environments, it can take different amounts of time for the
client socket to connect. If Karma cannot connect within the default timeout, you may see an
error similar to the following:
ChromeHeadless has not captured in 60000ms, killing.
Trying to start ChromeHeadless again (1/2).
ChromeHeadless has not captured in 60000ms, killing.
Trying to start ChromeHeadless again (2/2).
ChromeHeadless has not captured in 60000ms, killing.
ChromeHeadless failed 2 times(timeout). Giving up.If you see this error, you can try increasing the socket connection timeout.
Config 02 Files (`docs/config/02-files.md`)
The files array determines which files are included in the browser, watched, and served by Karma.
`files`
Type. Array
No Default. This property is mandatory.
Description. Each item is either a string (equivalent to { pattern: "<string>" }) or an object with the following properties:
`pattern`
- Type. String
- No Default. This property is mandatory.
- Description. The pattern to use for matching. See below for details on how patterns are resolved.
`type`
- Type. String
- Default. Will attempt to determine type based on file extension. If that fails, defaults to
js. - Possible Values:
css- Include using<link rel="stylesheet">tag.html- Include using HTML Imports. Note that this feature is obsolete and does not work in the modern browsers.js- Include using<script></script>tag.module- Include using<script type="module"></script>tag.dom- Inline content of the file in the page. This can be used, for example, to test components combining HTML and JS.
- Description. The type determines the mechanism for including the file.
`watched`
- Type. Boolean
- Default.
true - Description. If
autoWatchistrueall files that have setwatchedto true will be watched for changes.
`included`
Type. Boolean
Default.
trueDescription. Should the files be included in the browser using
<script>tag? Usefalseif you want to load them manually, eg.
using Require.js.If a file is covered by multiple patterns with different
includeproperties, the most specific pattern takes
precedence over the other.The specificity of the pattern is defined as a six-tuple, where larger tuple implies lesser specificity:
(nglob parts, nglob star, nstar, next glob, nrange, noptional).
Tuples are compared lexicographically.The nglob parts is the number of patterns after the bracket sections are expanded. E.g. the
the pattern {0...9} will yield nglob parts=10. The rest of the tuple is decided as the least
specific of each expanded pattern.
`served`
- Type. Boolean
- Default.
true - Description. Should the files be served by Karma's webserver?
`nocache`
- Type. Boolean
- Default.
false - Description. Should the files be served from disk on each request by Karma's webserver?
`integrity`
- Type. String
- Default.
undefined - Description. Set the
integrityHTML attribute value to the<script>or the<link>tag loading the resource that matches the given pattern if the pattern is an absolute URL.
Pattern matching and `basePath`
- All of the relative patterns will get resolved using the
basePathfirst. - If the
basePathis a relative path, it gets resolved to the
directory where the configuration file is located. - Eventually, all the patterns will get resolved into files using
glob, so you can use minimatch expressions liketest/unit/**/*.spec.js.
Ordering
- The order of patterns determines the order in which files are included in the browser.
- Multiple files matching a single pattern are sorted alphabetically.
- Each file is included exactly once. If multiple patterns match the
same file, it's included as if it only matched the first pattern.
Preprocessor transformations
Depending on preprocessor configuration, be aware that files loaded may be transformed and no longer available in
their native format. For instance, if html2js preprocessor is enabled, the actual .html files are no longer
served - but rather available as window.__html__['my.html']. Read more about preprocessors.
Complete example
Here is a complete example showing the different options possible:
files: [
// Detailed pattern to include a file. Similarly other options can be used
{ pattern: 'lib/angular.js', watched: false },
// Prefer to have watched false for library files. No need to watch them for changes
// simple pattern to load the needed testfiles
// equal to {pattern: 'test/unit/*.spec.js', watched: true, served: true, included: true}
'test/unit/*.spec.js',
// this file gets served but will be ignored by the watcher
// note if html2js preprocessor is active, reference as `window.__html__['compiled/index.html']`
{pattern: 'compiled/index.html', watched: false},
// this file only gets watched and is otherwise ignored
{pattern: 'app/index.html', included: false, served: false},
// this file will be served on demand from disk and will be ignored by the watcher
{pattern: 'compiled/app.js.map', included: false, served: true, watched: false, nocache: true}
],Loading files from another server
Pattern can also be an absolute URL. This allows including files which are not served by Karma.
Example:
config.set({
files: [
'https://example.com/my-lib.js',
{ pattern: 'https://example.com/my-lib', type: 'js' }
]
})Absolute URLs have some special rules comparing to the regular file paths:
- Globing is not support, so each URL must be specified as a separate pattern.
- Most of the regular options are not supported:
watchedis alwaysfalseincludedis alwaystrueservedis alwaysfalsenocacheis alwaysfalse
Loading Assets
By default all assets are served at http://localhost:[PORT]/base/
Example for loading images
files: [
{pattern: 'test/images/*.jpg', watched: false, included: false, served: true, nocache: false}
],The pattern is a glob which matches the specified image assets. Watched and included are not necessary as images are not tests. However, they will need to be served to the browser.
In this case an image would be accessed at http://localhost:[PORT]/base/test/images/[MY IMAGE].jpg
Notice the base in the URL, it is a reference to your basePath. You do not need to replace or provide your own base.
In addition, you can use a proxy
proxies: {
"/img/": "http://localhost:8080/base/test/images/"
},Now you can fetch images in test/images at http://localhost:8080/img/[MY IMAGE].jpg
Change 8080 to the port you use
You can also use proxies without specifying the protocol, hostname, and port
proxies: {
"/img/": "/base/test/images/"
},Webserver features
- Range requests.
- In-memory caching of files.
- Watching for updates in the files.
- Proxies to alter file paths.
- Support for custom middlewares (the
middlewareconfiguration option).
Config 03 Browsers (`docs/config/03-browsers.md`)
Capturing browsers on your own can be a tedious and time-consuming task. However, Karma can automate this for you. Simply add the browsers you would like to capture into the configuration file.
browsers: ['Chrome']Then, Karma will take care of auto-capturing these browsers, as well as killing them after the job is over.
Note: Most of the browser launchers need to be loaded as plugins.
Available browser launchers
- Chrome and Chrome Canary
- Firefox
- Safari
- PhantomJS
- JSDOM
- Opera
- Internet Explorer
- SauceLabs
- BrowserStack
- many more
Here's an example of how to add Firefox to your testing suite:
# Install the launcher first with npm:
$ npm install karma-firefox-launcher --save-devAnd then, inside your configuration file, add the browser name in browsers array.
module.exports = function(config) {
config.set({
browsers : ['Chrome', 'Firefox']
});
};Also, keep in mind that the browsers configuration setting is empty by default.
Of course, you can write custom plugins too!
Capturing any browser manually
You can also capture browsers by simply opening http://<hostname>:/, where <hostname> is the IP
address or hostname of the machine where the Karma server is running and `` is the port where the Karma
server is listening (by default it's 9876). With the default settings in place, just point your browser to http://localhost:9876/.
This allows you to capture a browser on any device, such as a tablet or a phone, that is on the same network
as the machine running Karma (or using a local tunnel).
Configured launchers
Some of the launchers can also be configured:
sauceLabs: {
username: 'michael_jackson'
}Or defined as a configured launcher:
customLaunchers: {
chrome_without_security: {
base: 'Chrome',
flags: ['--disable-web-security']
},
sauce_chrome_win: {
base: 'SauceLabs',
browserName: 'chrome',
platform: 'windows'
}
}A display name can be set for any custom launcher. If set, this name will be used for reporting instead of the
user agent. Here is a code snippet example explaining how to set a display name for a custom launcher.
customLaunchers: {
chrome_without_security: {
base: 'Chrome',
flags: ['--disable-web-security'],
displayName: 'Chrome w/o security'
}
}If the definition is as above, the browser will be displayed as Chrome w/o security in logs and reports.
Correct path to browser binary
Each plugin has some default paths where to find the browser binary on particular OS.
You can override these settings by _BIN ENV variable, or alternatively by creating a symlink.
POSIX shells
# Changing the path to the Chrome binary
$ export CHROME_BIN=/usr/local/bin/my-chrome-build
# Changing the path to the Chrome Canary binary
$ export CHROME_CANARY_BIN=/usr/local/bin/my-chrome-build
# Changing the path to the PhantomJs binary
$ export PHANTOMJS_BIN=$HOME/local/bin/phantomjsWindows cmd.exe
C:> SET IE_BIN=C:\Program Files\Internet Explorer\iexplore.exeWindows Powershell
$Env:FIREFOX_BIN = 'c:\Program Files (x86)\Mozilla Firefox 4.0 Beta 6\firefox.exe'Custom browsers
// in the karma.conf.js
browsers: ['/usr/local/bin/custom-browser.sh'],
// from cli
karma start --browsers /usr/local/bin/custom-browser.shThe browser scripts need to take one argument, which is the URL with the ID-parameter to be used to connect to the server. The supplied ID is used by the server to keep track of which specific browser is captured.
Config 04 Preprocessors (`docs/config/04-preprocessors.md`)
Preprocessors in Karma allow you to do some work with your files before
they get served to the browser. These are configured in the preprocessors block
of the configuration file:
preprocessors: {
'**/*.coffee': ['coffee'],
'**/*.tea': ['coffee'],
'**/*.html': ['html2js']
},Note: There are multiple expressions referencing the "coffee" preprocessor in this example, as a preprocessor
can be listed more than once as another way to specify multiple file path expressions.
Note: Most of the preprocessors need to be loaded as plugins.
Available Preprocessors
- coffee
- html2js
- Note any .html files listed in the files section must be referenced at run time as
window.__html__['template.html']. Learn more. - If this preprocessor is disabled, included .html files will need
base/added to beginning of their path reference. See discussion in issue 788.
- Note any .html files listed in the files section must be referenced at run time as
- coverage
- ng-html2js
- many more
Here's an example of how to add the CoffeScript preprocessor to your testing suite:
# Install it first with npm
$ npm install karma-coffee-preprocessor --save-devAnd then inside your configuration file...
module.exports = function(config) {
config.set({
preprocessors: {
'**/*.coffee': ['coffee']
}
});
};Of course, you can write custom plugins too!
Configured Preprocessors
Some of the preprocessors can also be configured:
coffeePreprocessor: {
options: {
bare: false
}
}Or define a configured preprocessor:
customPreprocessors: {
bare_coffee: {
base: 'coffee',
options: {bare: true}
}
}Mini matching
The keys of the preprocessors config object are used to filter the files specified in
the files configuration.
- First the file paths are expanded to an absolute path, based on the
basePathconfiguration and the directory of the configuration file. See
files for more information on that. - Then the newly expanded path is matched using minimatch against the specified key.
So for example the path /my/absolute/path/to/test/unit/file.coffee matched against
the key **/*.coffee would return true, but matched against just *.coffee it would
return false and the preprocessor would not be executed on the CoffeeScript files.
Order of execution
If a file matches only one key in the preprocessors config object, then karma
will execute the preprocessors over that file in the order they are listed in
the corresponding array. So for instance, if the config object is:
preprocessors: {
'*.js': ['a', 'b']
}Then karma will execute 'a' before executing 'b'.
If a file matches multiple keys, karma will use the config.preprocessor_priority map to control the execution order. The config.preprocessor_priority should be an object with property names equal to the preprocessor names and property values equal to the priority of execution. Higher priority preprocessors are run earlier. The default priority is 0.
If this config option is not set, karma will do its best to execute the preprocessors in a reasonable order. So if you have:
preprocessors: {
'*.js': ['a', 'b'],
'a.*': ['b', 'c']
}then for a.js, karma will run 'a' then 'b' then 'c'. If two lists contradict each other, like:
preprocessors: {
'*.js': ['a', 'b'],
'a.*': ['b', 'a']
}then karma will arbitrarily pick one list to prioritize over the other. In a
case like:
preprocessors: {
'*.js': ['a', 'b', 'c'],
'a.*': ['c', 'b', 'd']
}Then 'a' will definitely be run first, 'd' will definitely be run last, but
it's arbitrary if karma will run 'b' before 'c' or vice versa.
Config 05 Plugins (`docs/config/05-plugins.md`)
Karma can be easily extended through plugins. In fact, all the existing preprocessors, reporters, browser launchers and frameworks are plugins.
You can install existing plugins from npm or you can write your own plugins for Karma.
Installing Plugins
The recommended way to install plugins is to add them as project dependencies in your package.json:
{
"devDependencies": {
"karma": "~0.10",
"karma-mocha": "~0.0.1",
"karma-growl-reporter": "~0.0.1",
"karma-firefox-launcher": "~0.0.1"
}
}Therefore, a simple way to install a plugin is:
npm install karma-<plugin name> --save-devLoading Plugins
By default, Karma loads plugins from all sibling npm packages which have a name starting with karma-*.
You can also override this behavior and explicitly list plugins you want to load via the plugins configuration setting:
config.set({
plugins: [
// Load a plugin you installed from npm.
require('karma-jasmine'),
// Load a plugin from the file in your project.
require('./my-custom-plugin'),
// Define a plugin inline.
{ 'framework:xyz': ['factory', factoryFn] },
// Specify a module name or path which Karma will require() and load its
// default export as a plugin.
'karma-chrome-launcher',
'./my-fancy-plugin'
]
})Activating Plugins
Adding a plugin to the plugins array only makes Karma aware of the plugin, but it does not activate it. Depending on the plugin type you'll need to add a plugin name into frameworks, reporters, preprocessors, middleware or browsers configuration key to activate it. For the detailed information refer to the corresponding plugin documentation or check out Developing plugins guide for more in-depth explanation of how plugins work.
Dev 01 Contributing (`docs/dev/01-contributing.md`)
pageTitle: Contributing to Karma
Working on your first Pull Request? You can learn how from this free series
How to Contribute to an Open Source Project on GitHub
You want to contribute to Karma? That is truly great!
Here are some tips to get you started...
Help others
The best way to start contributing to any open source project is to help other people.
You can answer questions on the Gitter or Stack Overflow.
Either find something you already know the answer for, or something you feel interested in and
dig into it a little bit to find the answer.
Soon, you will realize you know Karma pretty well...
Improve the documentation
You don’t feel like hacking on the code, but still want to help?
Improving the documentation is very valuable as it will help many others.
All the source code is in docs/.
Fix something that bothers you
Did you find a bug that really bothers you? It’s more likely it bothers other users too, and maybe
it’s not that hard to fix it! Try to find an existing issue. If it does not exist yet, create one.
Look into the code and let others know what solution you are thinking about.
Then, send a pull request and let other contributors review.
Here is some more info on how to set up your workspace and send a pull
request.
Fix something else
You want to contribute some code but not sure where to start? That's cool. Fortunately,
there are many issues labeled as "PR please". These are typically fairly simple issues with
a well-known, waiting just for you...
Here is a list
of all the issues for the core repo. In the same way, each plugin has "PR please" label as well...
Review others work
Check out the list of outstanding pull requests if there is something you might be interested in.
Maybe somebody is trying to fix that stupid bug that bothers you. Review the PR.
Do you have any better ideas how to fix this problem? Let us know...
I want to help more
Check out Maintaining Karma. Becoming a Karma maintainer is simple.
You just do it. There is no test to pass ;-)
Dev 02 Making Changes (`docs/dev/02-making-changes.md`)
If you are thinking about making Karma better, or you just want to hack on it, that’s great!
Here are some tips on how to set up a Karma workspace and how to send a good pull request.
Setting up the Workspace
- Make sure you have a GitHub account.
- Fork the repository on GitHub.
- Clone your forkbash
$ git clone https://github.com/<your-username>/karma.git $ cd karma - Install for developmentbash
$ npm install
Testing and Building
Run the tests via:
bash$ npm test # or you can run test suits individually $ npm run test:unit $ npm run test:e2e $ npm run test:clientLint the code via:
bash$ npm run lint # or you can also apply auto-fixes where possible $ npm run lint:fixBuild the client code via:
bash$ npm run build # or use the watch mode $ npm run build:watch
Changing the Code
Checkout a new branch and name it accordingly to what you intend to do:
- Features get the prefix
feature-. - Bug fixes get the prefix
fix-. - Improvements to the documentation get the prefix
docs-.
$ git checkout -b <branch_name>Open your favorite editor, make some changes, run the tests, change the code, run the tests,
change the code, run the tests, etc.
- Please follow http://nodeguide.com/style.html (with exception of 100 characters per line).
Sending a Pull Request
- Commit your changes (please follow commit message conventions):bash
$ git commit -m "..." - Verify that the last commit follows the conventions:bash
$ npm run commit:check - Push to your GitHub repo:bash
$ git push origin <branch_name> - Go to the GitHub page and click "Open a Pull request".
- Write a good description of the change.
After sending a pull request, other developers will review and discuss your change.
Please address all the comments. Once everything is all right, one of the maintainers will merge
your changes in.
Contributor License Agreement
Please sign our Contributor License Agreement (CLA) before sending pull requests.
For any code changes to be accepted, the CLA must be signed. It's a quick process, we promise!
- For individuals, we have a simple click-through form.
- For corporations we'll need you to print, sign and one of scan+email, fax or mail the form.
Additional Resources
Dev 03 Maintaining (`docs/dev/03-maintaining.md`)
pageTitle: Maintaining Karma
This document is for people working on Karma. It describes common tasks such as triaging or merging
pull requests.
If you are interested in contributing to Karma, you might check out Contributing to Karma.
We use gitter/karma-runner to talk about pull requests and issues, stuff like,
“hey this is important, can you look into it...”, “I’m not sure what to do about this issue...”.
Triaging issues
New issues pop up every day. We need to identify urgent issues (such as “nobody can install karma”),
close duplicates, answer questions, etc.
See angular/TRIAGING.md for more info.
An issue or pull request is untriaged (needs to be triaged) when it is not assigned to any milestone.
Merging a pull request
Please, make sure:
- CI build is green.
- At least one owner (other than you) approved the PR
- by commenting “LGTM” or something like that.
- if it’s just a simple docs change or a typo fix, feel free to skip this step.
- All the commits follow the convention.
- This is very important, because the auto-release tasks depend on it.
- Commits are squashed. Each change is a single commit.
- e.g. if the PR contains two changes such as,
fix(web-server): xxxand thenstyle(web-server): missing semicolons; it should be two separate changes - e.g. if the first commit is
fix(web-server): serve binary filesand a second commit is “fix unit tests broken in the previous commit”, you should squash them into a single commit.
- e.g. if the PR contains two changes such as,
- It’s alright to ask the author of the pull request to fix any of the above.
Releasing npm
For core collaborators with admin rights.
- Be on a good network that won't go down in the middle.
- Make sure you are sync to upstream master.
echo $GH_TOKEN- If not set, set GH_TOKEN from https://github.com/settings/tokens/new
npm login karmarunnerbot- The password is known to authorized releasers.
grunt release
If the release fails, check the state of the git tags pushed to github. You may have to delete one.
Ownership
Every project has one or more owners (or “maintainers”), listed in owners field of thepackage.json. Typically, owners have push permissions.
Being a maintainer of one plugin doesn’t mean you can’t contribute to some other plugins.
In fact, you can be a maintainer of multiple projects. The main point is to have people who are
familiar with the codebase and therefore can better decide what a good change is or not.
Becoming a maintainer
If you are interested in becoming a Karma maintainer, start by triaging issues, reviewing pull
requests and stop by at gitter/karma-runner. Once we see you are helping, we will give you push
permissions. Being a maintainer is not an obligation. You can help when you have time and be less
active when you don’t. If you get a new job and get busy, that’s alright.
These are all just recommendations, something we found to be helpful for us to be more efficient.
Nothing is set in a stone. If you feel like there is a way to improve this workflow,
please send a proposal to [email protected].
Dev 04 Public Api (`docs/dev/04-public-api.md`)
Most of the time, you will be using Karma directly from the command line.
You can, however, call Karma programmatically from your node module. Here is the public API.
karma.Server(options, [callback=process.exit])
`constructor`
- Returns:
Serverinstance.
Usage
Notice the capital 'S' on require('karma').Server.
Deprecated Behavior
The following still works, but the way it behaves is deprecated and will be
changed in a future major version.
var Server = require('karma').Server
var karmaConfig = {port: 9876}
var server = new Server(karmaConfig, function(exitCode) {
console.log('Karma has exited with ' + exitCode)
process.exit(exitCode)
})New Behavior
const karma = require('karma')
const parseConfig = karma.config.parseConfig
const Server = karma.Server
parseConfig(
null,
{ port: 9876 },
{ promiseConfig: true, throwErrors: true }
).then(
(karmaConfig) => {
const server = new Server(karmaConfig, function doneCallback(exitCode) {
console.log('Karma has exited with ' + exitCode)
process.exit(exitCode)
})
},
(rejectReason) => { /* respond to the rejection reason error */ }
);`server.start()`
Equivalent of karma start.
server.start()`server.refreshFiles()`
Trigger a file list refresh. Returns a promise.
server.refreshFiles()`server.refreshFile(path)`
Trigger a file refresh. Returns a promise.
server.refreshFile('src/js/module-dep.js')Events
The server object is an EventEmitter. You can simply listen to events like this:
server.on('browser_register', function (browser) {
console.log('A new browser was registered')
})`listening`
Arguments:
port: Port number
Begin accepting connections on the specified port.
`browser_register`
Arguments:
browser: The browser instance
A new browser was opened, but is not ready yet.
`browser_error`
Arguments:
browser: The browser instanceerror: The error that occurred
There was an error in this browser instance.
`browser_start`
Arguments:
browser: The browser instanceinfo: Details about the run
A test run is beginning in this browser.
`browser_complete`
Arguments:
browser: The browser instanceresult: Test results
A test run has completed in this browser.
`browsers_change`
Arguments:
browsers: A collection of browser instances
The list of browsers has changed.
`browsers_ready`
All browsers are ready for execution
`run_start`
Arguments:
browsers: A collection of browser instances on which tests are executed
A test run starts.
`run_complete`
Arguments:
browsers: A collection of browser instancesresults: A list of results
This event gets triggered whenever all the browsers, which belong to a test run, finish. For example, on a run that has 3 browsers, one would expect 3 browser_complete events before the run_complete one.
karma.runner
`runner.run(options, [callback=process.exit])`
- Returns:
EventEmitter
The equivalent of karma run.
Usage
Deprecated Behavior
The following still works, but the way it behaves is deprecated and will be
changed in a future major version.
var runner = require('karma').runner
runner.run({port: 9876}, function(exitCode) {
console.log('Karma has exited with ' + exitCode)
process.exit(exitCode)
})New Behavior
const karma = require('karma')
karma.config.parseConfig(
null,
{ port: 9876 },
{ promiseConfig: true, throwErrors: true }
).then(
(karmaConfig) => {
karma.runner.run(karmaConfig, function doneCallback(exitCode, possibleErrorCode) {
console.log('Karma has exited with ' + exitCode)
process.exit(exitCode)
})
},
(rejectReason) => { /* respond to the rejection reason error */ }
);`callback` argument
The callback receives the exit code as the first argument.
If there is an error, the error code will be provided as the second parameter to
the error callback.
runner Events
runner.run() returns an EventEmitter which emits a progress event passing
the reporter output as a Buffer object.
You may listen for that event to print the reporter output to the console:
runner.run({port: 9876}).on('progress', function(data) {
process.stdout.write(data)
})karma.stopper
`stopper.stop(options, [callback=process.exit])`
This function will signal a running server to stop. The equivalent ofkarma stop.
Usage
Deprecated Behavior
The following still works, but the way it behaves is deprecated and will be
changed in a future major version.
var stopper = require('karma').stopper
stopper.stop({port: 9876}, function(exitCode) {
if (exitCode === 0) {
console.log('Server stop as initiated')
}
process.exit(exitCode)
})New Behavior
const karma = require('karma')
karma.config.parseConfig(
null,
{ port: 9876 },
{ promiseConfig: true, throwErrors: true }
).then(
(karmaConfig) => {
karma.stopper.stop(karmaConfig, function doneCallback(exitCode, possibleErrorCode) {
if (exitCode === 0) {
console.log('Server stop as initiated')
}
process.exit(exitCode)
})
},
(rejectReason) => { /* respond to the rejection reason error */ }
);`callback` argument
The callback receives the exit code as the first argument.
If there is an error, the error code will be provided as the second parameter to
the error callback.
karma.config
`config.parseConfig([configFilePath], [cliOptions], [parseOptions])`
This function will load given config file and returns a filled config object.
This can be useful if you want to integrate karma into another tool and want to load
the karma config while honoring the karma defaults.
Usage
Deprecated Behavior
The following still works, but the way it behaves is deprecated and will be
changed in a future major version.
const cfg = require('karma').config;
const path = require('path');
// Read karma.conf.js, but override port with 1337
const karmaConfig = cfg.parseConfig(
path.resolve('./karma.conf.js'),
{ port: 1337 }
);The new behavior in the future will involve throwing exceptions instead of
exiting the process and asynchronous config files will be supported through the
use of promises.
New Behavior
const cfg = require('karma').config;
const path = require('path');
// Read karma.conf.js, but override port with 1337
cfg.parseConfig(
path.resolve('./karma.conf.js'),
{ port: 1337 },
{ promiseConfig: true, throwErrors: true }
).then(
(karmaConfig) => { /* use the config with the public API */ },
(rejectReason) => { /* respond to the rejection reason error */ }
);`configFilePath` argument
- Type: String |
null|undefined - Default Value:
undefined
A string representing a file system path pointing to the config file whose
default export is a function that will be used to set Karma configuration
options. This function will be passed an instance of the Config class as its
first argument. If this option is not provided, then only the options provided
by the cliOptions argument will be set.
- JavaScript must use CommonJS modules.
- ECMAScript modules are not currently supported by Karma when using
JavaScript.- Other formats, such as TypeScript, may support ECMAScript modules.
`cliOptions` argument
- Type: Object |
null|undefined - Default Value:
undefined
An object whose values will take priority over options set in the config file.
The config object passed to function exported by the config file will already
have these options applied. Any changes the config file makes to these options
will effectively be ignored in the final configuration.
Supports all the same options as the config file and is applied using the sameconfig.set() method.
The expected source of this argument is parsed command line options, but
programatic users may construct this object or leave it out entirely.
`parseOptions` argument
- Type: Object |
null|undefined - Default Value:
undefined
parseOptions is an object whose properties are configuration options that
allow additional control over parsing and opt-in access to new behaviors or
features.
These options are only related to parsing configuration files and object and are
not related to the configuration of Karma itself.
`parseOptions.promiseConfig` option
- Type: Boolean
- Default Value:
false
When parseOptions.promiseConfig === true, then parseConfig will return a
promise instead of a configuration object.
When this option is true, then the function exported by the config file may
return a promise. The resolution of that promise indicates that all asynchronous
activity has been completed. Internally, the resolved/fulfilled value is
ignored. As with synchronous usage, all changes to the config object must be
done with the config.set() method.
If the function exported by the config file does not return a promise, then
parsing is completed and an immediately fulfilled promise is returned.
Whether the function exported by the config file returns a promise or not, the
promise returned by parseConfig() will resolve with a parsed configuration
object, an instance of the Config class, as the value.
In most cases, parseOptions.throwErrors = true should also be set. This
disables process exiting and allows errors to result in rejected promises.
`parseOptions.throwErrors` option
- Type: Boolean
- Default Value:
false
In the past, parseConfig() would call process.exit(exitCode) when it
encountered a critical failure. This meant that your own code had no way of
responding to failures before the Node.js process exited.
By passing parseOptions.throwErrors = true, parseConfig() will disable
process exiting.
For synchronous usage, it will throw an exception instead of exiting the
process. Your code can then catch the exception and respond how ever it needs
to.
If the asynchronous API (parseOptions.promiseConfig = true) is being used,
then parseOptions.throwErrors = true allows the promise to be rejected
instead of exiting the process.
`karma.constants`
`constants.VERSION`
The current version of karma
`constants.DEFAULT_PORT`
The default port used for the karma server
`constants.DEFAULT_HOSTNAME`
The default hostname used for the karma server
`constants.DEFAULT_LISTEN_ADDR`
The default address use for the karma server to listen on
`constants.LOG_DISABLE`
The value for disabling logs
`constants.LOG_ERROR`
The value for the log error level
`constants.LOG_WARN`
The value for the log warn level
`constants.LOG_INFO`
The value for the log info level
`constants.LOG_DEBUG`
The value for the log debug level
`constants.LOG_PRIORITIES`
An array of log levels in descending order, i.e. LOG_DISABLE, LOG_ERROR, LOG_WARN, LOG_INFO, and LOG_DEBUG
`constants.COLOR_PATTERN`
The default color pattern for log output
`constants.NO_COLOR_PATTERN`
The default pattern for log output without color
`constants.CONSOLE_APPENDER`
The default console appender
`constants.EXIT_CODE`
The exit code
Dev 05 Plugins (`docs/dev/05-plugins.md`)
pageTitle: Developing Plugins
Karma can be extended through plugins. There are five kinds of plugins: framework, reporter, launcher, preprocessor and middleware. Each type allows to modify a certain aspect of the Karma behavior.
- A framework connects a testing framework (like Mocha) to a Karma API, so browser can send test results back to a Karma server.
- A reporter defines how test results are reported to a user.
- A launcher allows Karma to launch different browsers to run tests in.
- A preprocessor is responsible for transforming/transpiling source files before loading them into a browser.
- A middleware can be used to customise how files are served to a browser.
Dependency injection
Karma is assembled using dependency injection. It is important to understand this concept to be able to develop plugins.
On the very high level you can think of Karma as an object where each key (a DI token) is mapped to a certain Karma object (a service). For example, config DI token maps to Config instance, which holds current Karma configuration. Plugins can request (or inject) various Karma objects by specifying a corresponding DI token. Upon injection a plugin can interact with injected services to implement their functionality.
There is no exhaustive list of all available services and their DI tokens, but you can discover them by reading Karma's or other plugins' source code.
Plugin structure
Each plugin is essentially a service with its associated DI token. When user activates a plugin in their config, Karma looks for a corresponding DI token and instantiates a service linked to this DI token.
To declare a plugin one should define a DI token for the plugin and explain Karma how to instantiate it. A DI token consists of two parts: a plugin type and plugin's unique name. The former defines what a plugin can do, requirements to the service's API and when it is instantiated. The latter is a unique name, which a plugin user will use to activate a plugin.
It is totally valid for a plugin to define multiple services. This can be done by adding more keys to the object exported by the plugin. Common example of this would be framework + reporter plugins, which usually come together.
Let's make a very simple plugin, which prints "Hello, world!" when instantiated. We'll use a framework type as it is instantiated early in the Karma lifecycle and does not have any requirements to its API. Let's call our plugin "hello", so its unique name will be hello. Joining these two parts we get a DI token for our plugin framework:hello. Let's declare it.
// hello-plugin.js
// A factory function for our plugin, it will be called, when Karma needs to
// instantiate a plugin. Normally it should return an instance of the service
// conforming to the API requirements of the plugin type (more on that below),
// but for our simple example we don't need any service and just print
// a message when function is called.
function helloFrameworkFactory() {
console.log('Hello, world!')
}
module.exports = {
// Declare the plugin, so Karma knows that it exists.
// 'factory' tells Karma that it should call `helloFrameworkFactory`
// function and use whatever it returns as a service for the DI token
// `framework:hello`.
'framework:hello': ['factory', helloFrameworkFactory]
};// karma.conf.js
module.exports = (config) => {
config.set({
plugins: [
require('./hello-plugin')
],
// Activate our plugin by specifying its unique name in the
// corresponding configuration key.
frameworks: ['hello']
})
}Injecting dependencies
In "Dependency injection" section we discussed that it is possible to inject any Karma services into a plugin and interact with them. This can be done by setting an $inject property on the plugin's factory function to an array of DI tokens plugin wishes to interact with. Karma will pick up this property and pass requested services to the factory functions as parameters.
Let's make the hello framework a bit more useful and make it add hello.js file to the files array. This way users of the plugin can, for example, access a function defined in hello.js from their tests.
// hello-plugin.js
// Add parameters to the function to receive requested services.
function helloFrameworkFactory(config) {
config.files.unshift({
pattern: __dirname + '/hello.js',
included: true,
served: true,
watched: false
})
}
// Declare DI tokens plugin wants to inject.
helloFrameworkFactory.$inject = ['config']
module.exports = {
'framework:hello': ['factory', helloFrameworkFactory]
};The Karma config is unchanged and is omitted for brevity. See above example for the plugin usage.
Note: Currently, Karma uses node-di library as a DI implementation. The library is more powerful than what's documented above, however, the DI implementation may change in the future, so we recommend not to rely on the node-di implementation details.
Plugin types
This section outlines API requirements and conventions for different plugin types. There also links to some plugins, which you can use for inspiration.
Frameworks
- example plugins: karma-jasmine, karma-mocha, karma-requirejs
- use naming convention is
karma-* - use npm keywords
karma-plugin,karma-framework.
A framework connects existing testing libraries to Karma's API, so that their results can be displayed in a browser and sent back to the server.
Karma frameworks must implement a window.__karma__.start method that Karma will
call to start test execution. This function is called with an object that has methods
to send results back to karma:
.resulta single test has finished.completethe client completed execution of all the tests.erroran error happened in the client.infoother data (e.g. number of tests or debugging messages)
Most commonly you'll use the result method to send individual test success or failure
statuses. The method takes an object of the form:
{
// test id
id: String,
// test description
description: String,
// the suite to which this test belongs. potentially nested.
suite: Array[String],
// an array of string error messages that might explain a failure.
// this is required if success is false.
log: Array[String],
success: Boolean, // pass / fail
skipped: Boolean // skipped / ran
}Reporters
- example plugins: karma-growl-reporter, karma-junit-reporter, karma-material-reporter
- use naming convention is
karma-*-reporter - use npm keywords
karma-plugin,karma-reporter
Launchers
- example plugins: karma-chrome-launcher, karma-sauce-launcher
- use naming convention is
karma-*-launcher - use npm keywords
karma-plugin,karma-launcher
Preprocessors
- example plugins: karma-coffee-preprocessor, karma-ng-html2js-preprocessor
- use naming convention is
karma-*-preprocessor - user npm keywords
karma-plugin,karma-preprocessor
A preprocessor is a function that accepts three arguments (content, file, and next), mutates the content in some way, and passes it on to the next preprocessor.
- arguments passed to preprocessor plugins:
contentof the file being processedfileobject describing the file being processed- path: the current file, mutable file path. e. g.
some/file.coffee->some/file.coffee.jsThis path is mutable and may not actually exist. - originalPath: the original, unmutated path
- encodings: A mutable, keyed object where the keys are a valid encoding type ('gzip', 'compress', 'br', etc.) and the values are the encoded content. Encoded content should be stored here and not resolved using
next(null, encodedContent) - type: determines how to include a file, when serving
- path: the current file, mutable file path. e. g.
nextfunction to be called when preprocessing is complete, should be called asnext(null, processedContent)ornext(error)
Crazier stuff
As Karma is assembled by dependency injection, a plugin can ask for pretty much any Karma component and interact with it. There are a couple of plugins that do more interesting stuff like this, check out karma-closure, karma-intellij.
Dev 06 Git Commit Msg (`docs/dev/06-git-commit-msg.md`)
showInMenu: false
In the repository we use and enforce the commit message conventions. The conventions are verified using commitlint with Angular config.
The reasons for these conventions:
- automatic generating of the changelog
- simple navigation through git history (e.g. ignoring style changes)
Format of the commit message:
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>Example commit message:
fix(middleware): ensure Range headers adhere more closely to RFC 2616
Add one new dependency, use `range-parser` (Express dependency) to compute
range. It is more well-tested in the wild.
Fixes #2310Message subject (first line)
The first line cannot be longer than 72 characters and should be followed by a blank line. The type and scope should always be lowercase as shown below.
Allowed `` values:
- feat for a new feature for the user, not a new feature for build script. Such commit will trigger a release bumping a MINOR version.
- fix for a bug fix for the user, not a fix to a build script. Such commit will trigger a release bumping a PATCH version.
- perf for performance improvements. Such commit will trigger a release bumping a PATCH version.
- docs for changes to the documentation.
- style for formatting changes, missing semicolons, etc.
- refactor for refactoring production code, e.g. renaming a variable.
- test for adding missing tests, refactoring tests; no production code change.
- build for updating build configuration, development tools or other changes irrelevant to the user.
Example `` values:
- init
- runner
- watcher
- config
- web-server
- proxy
- etc.
The <scope> can be empty (e.g. if the change is a global or difficult
to assign to a single component), in which case the parentheses are
omitted. In smaller projects such as Karma plugins, the <scope> is empty.
Message body
Just as in the <subject>, use the imperative, present tense: "change" not "changed" nor "changes". Message body should include motivation for the change and contrasts with previous behavior.
Message footer
Referencing issues
Closed issues should be listed on a separate line in the footer prefixed with "Closes" keyword like this:
Closes #234or in the case of multiple issues:
Closes #123, #245, #992Breaking changes
All breaking changes have to be mentioned in footer with the
description of the change, justification and migration notes.
BREAKING CHANGE:
`port-runner` command line option has changed to `runner-port`, so that it is
consistent with the configuration file syntax.
To migrate your project, change all the commands, where you use `--port-runner`
to `--runner-port`.Any commit with the breaking change section will trigger a MAJOR release and appear on the changelog independently of the commit type.
This document is based on Angular Commit Message Format. See the commit history for examples of properly-formatted commit messages.
Intro 01 Installation (`docs/intro/01-installation.md`)
Karma runs on Node.js and is available as an npm package.
Installing Node.js
On Mac or Linux we recommend using NVM. On Windows, download Node.js
from the official site or use the NVM PowerShell Module.
Karma works on all LTS releases of Node.js.
Installing Karma and plugins
The recommended approach is to install Karma (and all the plugins your project needs) locally in
the project's directory.
# Install Karma:
$ npm install karma --save-dev
# Install plugins that your project needs:
$ npm install karma-jasmine karma-chrome-launcher jasmine-core --save-devThis will install karma, karma-jasmine, karma-chrome-launcher and jasmine-core packages into node_modules in your current
working directory and also save these as devDependencies in package.json, so that any
other developer working on the project will only have to do npm install in order to get all these
dependencies installed.
# Run Karma:
$ ./node_modules/karma/bin/karma startCommandline Interface
Typing ./node_modules/karma/bin/karma start sucks and so you might find it useful to install karma-cli globally. You will need to do this if you want to run Karma on Windows from the command line.
$ npm install karma-cliThen, you can run Karma simply by karma from anywhere and it will always run the local version.
Intro 02 Configuration (`docs/intro/02-configuration.md`)
In order to serve you well, Karma needs to know about your project in order to test it
and this is done via a configuration file. This page explains how to create such a configuration file.
See configuration file docs for more information about the syntax and all the available options.
Generating the config file
The configuration file can be generated using karma init:
$ karma init my.conf.js
Which testing framework do you want to use?
Press tab to list possible options. Enter to move to the next question.
> jasmine
Do you want to use Require.js?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no
Do you want to capture a browser automatically?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome
> Firefox
>
What is the location of your source and test files?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Press Enter to move to the next question.
> *.js
> test/**/*.js
>
Should any of the files included by the previous patterns be excluded?
You can use glob patterns, eg. "**/*.swp".
Press Enter to move to the next question.
>
Do you want Karma to watch all the files and run the tests on change?
Press tab to list possible options.
> yes
Config file generated at "/Users/vojta/Code/karma/my.conf.js".The configuration file can be written in CoffeeScript as well.
In fact, if you execute karma init with a *.coffee extension such as karma init karma.conf.coffee, it will generate a CoffeeScript file.
Of course, you can write the config file by hand or copy-paste it from another project ;-)
Starting Karma
When starting Karma, the configuration file path can be passed in as the first argument.
By default, Karma will look for karma.conf.js or karma.conf.coffee in the current directory.
# Start Karma using your configuration:
$ karma start my.conf.jsFor more detailed information about the Karma configuration file, such as available options and features,
please read the configuration file docs.
Command line arguments
Some configurations, which are already present within the configuration file, can be overridden by specifying the configuration
as a command line argument for when Karma is executed.
karma start my.conf.js --log-level debug --single-runTry karma start --help if you want to see all available options.
Integrating with Grunt/Gulp
Intro 03 How It Works (`docs/intro/03-how-it-works.md`)
Karma is essentially a tool which spawns a web server that executes source code against test code for each of the browsers connected.
The results of each test against each browser are examined and displayed via the command line to the developer
such that they can see which browsers and tests passed or failed.
A browser can be captured either
- manually, by visiting the URL where the Karma server is listening (typically
http://localhost:9876/), - or automatically by letting Karma know which browsers to start when Karma is run (see browsers).
Karma also watches all the files, specified within the configuration file, and whenever any file changes, it triggers the test run by
sending a signal to the testing server to inform all of the captured browsers to run the test code again.
Each browser then loads the source files inside an IFrame, executes the tests and reports the results back to the server.
The server collects the results from all of the captured browsers and presents them to the developer.
This is only a very brief overview, as the internals of how Karma works aren't entirely necessary when using Karma.
Outline of workflow.
Here is roughly how Karma works:
After starting up, Karma loads plugins and the configuration file, then starts its local web server which listens for connections.
Any browser already waiting on websockets from the server will reconnect immediately. As part of loading the plugins, test reporters
register for 'browser' events so they are ready for test results.
Then karma launches zero, one, or more browsers, setting their start page the Karma server URL.
When the browsers connect, Karma serves a 'client.html' page; when this page runs in the browser it connects back to the server via websockets.
Once the server sees the websocket connection, it instructs the client -- over the websocket -- to execute tests. The client page opens an iframe with a 'context.html' page from the server. The server generates this context.html page using the configuration. This page includes the test framework adapter, the code to be tested, and the test code.
When the browser loads this context page, the onload event handler connects the context page to the client page via postMessage. The framework adapter is in charge at this point: it runs the test, reporting errors or success by messaging through the client page.
Messages sent to the client page are forwarded through the websocket to the Karma server. The server re-dispatches these messages as 'browser' events. The reporters listening to 'browser' events get the data; they may print it, save it to files, or forward the data to another service.
Since the data is sent by the test framework adapter to the reporter, adapters and reporters almost always come in pairs, like karma-jasmine and karma-jasmine-reporter. The detailed content of test-result data is of no concern to other parts of karma: only the reporter needs to know its format.
Karma has many variations and options that may cause different workflow with different configurations.
If you are interested in learning more about the design, Karma itself originates from a university thesis, which goes into detail about the design
and implementation, and it is available to read right here.
Intro 04 Faq (`docs/intro/04-faq.md`)
pageTitle: Frequently Asked Questions menuTitle: FAQ
The list below is a collection of common questions regarding Karma and its use.
If you have any other questions in mind, please visit the mailing list to let the community know.
Can I use Karma with testing framework X?
Yes. There are plugins for most of the common testing frameworks (such as Jasmine, Mocha, QUnit).
If there is no plugin for the testing framework you like, go ahead and write one. It is simple -
you can start by looking into the source code of the existing ones.
Can I use Karma to do end to end testing?
Karma has primarily been designed for low level (unit) testing. If it's an AngularJS app, you can
use Karma with the karma-ng-scenario plugin. However, we recommend Protractor for high-level testing.
Can I use Karma on Continuous Integration server ?
Of course! Check out the docs for Jenkins, Semaphore, TeamCity or Travis.
Which version of Karma should I use?
The latest stable version from npm (npm install karma). See versioning for more detailed information about Karma's release channels.
Which version of Node.js does Karma run with?
Karma works on all LTS versions of Node.js as specified by the Node.js Release Working Group. The Node.js version numbers are set in the package.json. Older versions of karma work with older versions of Node.js, but are not maintained or updated.
Intro 05 Troubleshooting (`docs/intro/05-troubleshooting.md`)
pageTitle: Troubleshooting menuTitle: Troubleshooting
karma has an extensive set of tests and we have limited time to help with bugs. Here are some suggestions to get you unstuck.
npm audit vulnerabilities
Please open a Pull Request that will fix the issue.
We get lots of these reports, from multiple automated services, from other projects, and from users. The vast majority are minor: please open a pull request if you want a fix. We only take direct action to fix serious issues that affect online users.
How Do I Debug a karma issue?
Many issues can be solved by reading the debug log or by using the browsers devtools:
Use `--log-level debug` to investigate server-side issues, especially configuration issues.
The DEBUG log includes a copy of the final 'config': note that plugins can alter the config and sometimes the settings you applied do not give the result you expected. The log includes both core karma lines and lines from plugins: use the logging prefix to determine if your issue may need to be reported to a karma plugin.
Use `--no-single-run` to investigate browser-side issues, especially global errors in test files.
The --no-single-run option causes the server to print a URL and wait. Open the URL in a browser and use the browsers devtools to investigate the problem. Typically you will want to open the URL, then click the DEBUG link in the upper right corner. That opens a new window with cleaner code for debugging.
Is your issue related to another tool?
Issues with Angular setups are probably better debugged by consulting with other Angular users. Issues with coverage are probably related to your config, the compiler for coverage instrumentation, or possibly karma-coverage.
Use the source!
karma is all JavaScript code: perhaps you can debug your issue by adding logging?
I'm getting an error during the installation related to the ```ws``` module, how can I solve it?
This is a common Windows issue, the compilation of the native ws module fails. Anyways, ws has a fallback JS implementation which npm should take care using it. All you need to do is make sure that you're using an up-to-date version of npm. To do that you can:
Update npm
$ npm install npm
or
Do a fresh NodeJS install
If you have issues to update npm, you can just go to the NodeJS download the current version. It will come with the latest npm version.
The browser just does not start. What's going on?
It's more likely Karma can't find the location of the browser binary (the execution file). You can fix this by setting
the appropriate environment variable with the correct path (Google Chrome, for instance, uses the CHROME_BIN environment variable).
Check out browsers for more information.
I'm getting a weird error from the browser, how can I debug it?
Go to the captured browser and click the "DEBUG" button (or open http://localhost:9876/debug.html)
and use the web inspector to see what's going on. (You may need to refresh the debug.html page for it to kick in once
the web inspector is open.)
I'm getting a syntax error from a HTML file. It looks like the preprocessor isn't working.
The patterns in the preprocessors configuration setting are resolved via the basePath setting.
See preprocessors for more information. You can also turn on debug logging (use --log-level debug when starting Karma)
and Karma will display which files are preprocessed.
I'm getting a `npm ERR! peerinvalid Peer` error. How can I fix that?
Try to remove karma and karma-* modules from your node_modules first (for instance rm -rf /usr/local/lib/node_modules/karma-*), then install Karma again.
My tests are running really slow. What's going on?
Make sure the Karma's tab is active. Browsers give inactive tabs only minimum CPU.
Note: If you can't find the solution for your issue here you can also ask for help in the mailing-list or Stack Overflow.
I'm really stuck. I tried every thing!
Because of the complexity of test setups, we rarely work to fix bugs without steps to reproduce. The best approach is to create a github project that installs all the components and reproduces the bug.
Plus 01 Requirejs (`docs/plus/01-requirejs.md`)
pageTitle: RequireJS menuTitle: RequireJS
To get Karma to run with Require.js we need two files:
karma.conf.js— which configures Karmatest-main.js— which configures Require.js for the tests
Let's imagine our app has a directory structure which looks something like this:
$ tree
.
|-- index.html
|-- karma.conf.js
|-- lib
| |-- jquery.js
| |-- require.js
| `-- underscore.js
|-- src
| |-- app.js
| `-- main.js
`-- test
|-- appSpec.js
`-- test-main.js
3 directories, 9 filesConfigure Karma
The first step is creating our karma.conf.js. We can do this from the
command line:
$ karma initThis will give you a series of prompts for things such as paths to the source and test
files as well as which browsers to capture.
In this example we'll use Jasmine, but other test frameworks work just
as well.
Choose "yes" for Require.js.
For the question "Which files do you want to include with <script>
tag?", we need to choose all files which are not loaded by Require.js.
Usually, you'll only need to include your test-main.js file, which has
the same role for your tests as main.js has for your app when using
Require.js.
For the question "What is the location of your source and test files?", we choose all the
files we want to load with Require.js. For this example we'll need:
lib/**/*.js— all external librariessrc/**/*.js— our source codetest/**/*Spec.js— all the tests
And then, when excluding files, type in src/main.js, as we don't want to actually
start the application in our tests.
Now your karma.conf.js should include:
// list of files / patterns to load in the browser
module.exports = function(config) {
config.set({
frameworks: ['jasmine', 'requirejs'],
files: [
{pattern: 'lib/**/*.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'test/**/*Spec.js', included: false},
'test/test-main.js'
],
// list of files to exclude
exclude: [
'src/main.js'
]
});
};The files property contains every file you want to be available to the
Karma runner. By default a script tag will be created for the files,
unless you use the included: false option.
If you want a script tag to be added before requirejs (to load an amd
compatible script before requirejs) then you must add the requirejs
and adapter script to the files list and remove requirejs from the
frameworks list. This allows you to control the order. For instance
to load knockout.js before requirejs...
config.set({
frameworks: ['jasmine'],
files: [
'knockout.js',
'node_modules/requirejs/require.js',
'node_modules/karma-requirejs/lib/adapter.js',
{pattern: 'lib/**/*.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'test/**/*Spec.js', included: false},
'test/test-main.js'
],Configuring Require.js
Just like any Require.js project, you need a main module to bootstrap
your tests. We do this in test/test-main.js.
Karma `/base` Directory
Karma serves files under the /base directory. So, on the server
requests to files will be served up underhttp://localhost:9876/base/*.
The Require.js config for baseUrl gives a starting context for modules
that load with relative paths. When setting this value for the Karma
server, it will need to start with /base. We want the baseUrl for our
tests to be the same folder as the base url we have in src/main.js, so
that relative requires in the source won’t need to change. So, as we
want our base url to be at src/, we need to write /base/src.
Require Each Test File
With Karma we don't need to list all test files ourselves as we can
easily find them from the files specified in test-main.js: Karma
includes all the files in window.__karma__.files, so by filtering this
array we find all our test files.
Now we can tell Require.js to load our tests, which must be done
asynchronously as dependencies must be fetched before the tests are run.
The test/test-main.js file ends up looking like this:
var TEST_REGEXP = /(spec|test)\.js$/i;
var allTestFiles = [];
// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
// If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
// then do not normalize the paths
var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');
allTestFiles.push(normalizedTestModule);
}
});
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: '/base/src',
// example of using a couple of path translations (paths), to allow us to refer to different library dependencies, without using relative paths
paths: {
'jquery': '../lib/jquery',
'underscore': '../lib/underscore',
},
// example of using a shim, to load non AMD libraries (such as underscore)
shim: {
'underscore': {
exports: '_'
}
},
// dynamically load all test files
deps: allTestFiles,
// we have to kickoff jasmine, as it is asynchronous
callback: window.__karma__.start
});Using Require.js in tests
Tests can now be written as regular Require.js modules. We wrap
everything in define, and inside we can use the regular test methods,
such as describe and it. Example:
define(['app', 'jquery', 'underscore', './test-helper'], function(App, $, _, testHelper) {
describe('just checking', function() {
testHelper.setup();
it('works for app', function() {
var el = $('<div></div>');
var app = new App(el);
app.render();
expect(el.text()).toEqual('require.js up and running');
});
it('works for underscore', function() {
// just checking that _ works
expect(_.size([1,2,3])).toEqual(3);
});
});
});Running the tests
We can now run the tests from the command line:
$ karma startIf you didn't configure Karma to watch all the files and run tests
automatically on any change, you can trigger the tests manually by
typing:
$ karma runHere is a running example of Karma with Require.js.
Plus 02 Travis (`docs/plus/02-travis.md`)
pageTitle: Travis CI menuTitle: Travis CI
Travis CI is a popular continuous integration service that
integrates with your Github repository to automatically run your
tests when the code is pushed. Integration is done by adding a simple
YAML file to your project root; Travis and Github take care of the
rest. Whenever tested, the Travis results will appear in your Github pull requests and your
history will be available within their control panel. This article assumes you
already have Travis account.
Configure Travis
Create a file in your project root called .travis.yml with the
following YAML content:
language: node_js
node_js:
- "4"Set up a Test Command
If you do not already have a package.json in your project root, create one now. Travis runs npm test to trigger your tests, so this
is where you tell Travis how to run your tests.
// ...snip...
"devDependencies": {
"karma": "~0.12"
},
// ...snip...
"scripts": {
"test": "karma start --single-run --browsers PhantomJS"
}
// ...snip...Travis will run npm install before every suite, so this is your
chance to specify any modules your app needs that Travis does not know
about like Karma.
Configure Travis with Firefox
Travis supports running a real browser (Firefox) with a virtual
screen. Just update your .travis.yml to set up the virtual screen
like this (if you're using Xenial):
language: node_js
node_js:
- "4"
dist: xenial
services:
- xvfbOr this, for Trusty and below:
language: node_js
node_js:
- "4"
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb startAnd now, you can run your tests on Firefox, just change the npm test
command to
karma start --browsers Firefox --single-runNotes
- Travis' Node environment has very little available. If the startup
process in Travis fails to check for missing module information and be sure to add them to yourpackage.jsondependencies. - Travis does not run on your local network so any code that attempts
to connect to resources should be stubbed out using Nock. - There are more options available to your
.travis.yml, such as
running scripts before the install or test run. There are hints in
the Travis docs for GUI apps configuration.
Plus 03 Jenkins (`docs/plus/03-jenkins.md`)
pageTitle: Jenkins CI menuTitle: Jenkins CI
Jenkins CI is one of the most popular continuous integration servers
in the market today. At some point while developing your AngularJS
project (hopefully early on), you might want to have automated tests run
off your code versioning system. Jenkins will help you with this task.
This tutorial assumes you have Jenkins already setup and running
on your CI environment.
Install Prerequisites
You need the following tools installed on your Jenkins CI server:
- Node
- Karma
The following Jenkins plugin is optional, but the next guidelines are based on it:
- EnvInject - it makes things easier under certain linux distributions and user permissions.
Configure Karma
Make the following additions and changes to your karma.conf.js
file as needed:
singleRun: true,
reporters: ['dots', 'junit'],
junitReporter: {
outputFile: 'test-results.xml'
},Please note the test-results.xml files will be written to subdirectories
named after the browsers the tests were run in inside the present working
directory (and you will need to tell Jenkins where to find them).
Create a new Jenkins Job
In Jenkins, start a new job for Angular/Karma with the basic
settings (Name, description, parameters, source code repo to pull
from, etc.)
Configure the Build Environment
First go to the job page and click on configure. Then in the Build
Environment sub-section, check the “Inject environment
variables to the build process' checkbox. A few textboxes will
appear and in the “Properties Content” box set the following:
$ PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
$ PHANTOMJS_BIN=/usr/local/bin/phantomjs #or wherever PhantomJS happens to be installedFurther down the page, in the Post-build Actions sub-section add aPublish JUnit test result report from the Post-build action drop
down menu. When the textbox labeled Test report XMLs appears, enter
the path to where the test-results.xml files are relative to the root of your
Jenkins job workspace (you can use wildcards for this, so **/test-results.xml
will find the file even if it was stored inside a browser-specific
subdirectory).
Plus 04 Semaphore (`docs/plus/04-semaphore.md`)
pageTitle: Semaphore CI menuTitle: Semaphore CI
Semaphore is a popular continuous integration service that
supports a wide range of programming languages. Up-to-date
versions of Firefox, PhantomJS and Node.js make it a good
testing ground for JavaScript applications. This article assumes
you already have a Semaphore account.
Configure Your Project
If you do not already have a package.json in your project root,
create one now. This will both document your configuration and
make it easy to run your tests. Here's an example:
// ...snip...
"devDependencies": {
"karma": "~0.10"
},
// ...snip...
"scripts": {
"test": "./node_modules/.bin/karma start --single-run --browsers PhantomJS"
}
// ...snip...Another option is to use Firefox as your test browser. To do this, change
the last part to:
"scripts": {
"test": "./node_modules/.bin/karma start --single-run --browsers Firefox"
}Now running npm test within your project will run your tests with Karma.
Add Your Project to Semaphore
Follow the process as shown in the screencast on the Semaphore docs.
After the analysis is finished, ignore the Ruby version Semaphore has set
for you, choose to customize your build commands and use these:
npm install
npm testThat's it - proceed to your first build. In case you're using Firefox as
your test browser, Semaphore will automatically run it on a virtual screen
during your builds.
Also, if necessary, build commands can be further customized at any time.
Plus 05 Cloud9 (`docs/plus/05-cloud9.md`)
Cloud9 IDE is an open source web-based cloud integrated development environment that supports
several programming languages, with a focus on the web stack (specifically JavaScript and NodeJS).
It is written almost entirely in JavaScript and uses NodeJS on the back-end.
Configuration
First, make sure the karma.conf.js includes the following entries:
hostname: process.env.IP,
port: process.env.PORTCapture the browser manually on the local machine
You can use any of your local browsers.
# Start Karma without browsers:
$ karma start --no-browsersNow, open http://.<cloud9User>.c9.io/ in your browser.
Run Karma unit tests with PhantomJS
It is also possible to run headless PhantomJS on the Cloud9 server.
# Install the PhantomJS plugin:
$ npm install karma-phantomjs-launcher
# Start Karma:
$ karma start --browsers PhantomJSPlus 06 Angularjs (`docs/plus/06-angularjs.md`)
pageTitle: AngularJS menuTitle: AngularJS
If you're using AngularJS, check out the AngularJS Generator, which makes use of the Karma Generator to setup a fully featured, testing-ready project.
Plus 07 Yeoman (`docs/plus/07-yeoman.md`)
Yeoman is a set of tools to make building web apps easier. Yeoman has support for Karma via the Karma Generator.
Plus 08 Emberjs (`docs/plus/08-emberjs.md`)
pageTitle: Ember.js menuTitle: Ember.js
To execute javascript unit and integration tests with ember.js follow the steps below:
install the qunit plugin
bashnpm install karma-qunit --save-devinstall the ember preprocessor plugin
bashnpm install karma-ember-preprocessor --save-devgenerate a configuration file for karma
bashkarma initnote -the above will walk you through the basic setup. An example configuration file that works with ember.js/qunit and phantomjs is below
javascriptmodule.exports = function(config) { config.set({ basePath: 'js', files: [ 'vendor/jquery/jquery.min.js', 'vendor/handlebars/handlebars.js', 'vendor/ember/ember.js', 'app.js', 'tests/*.js', 'templates/*.handlebars' ], browsers: ['PhantomJS'], singleRun: true, autoWatch: false, frameworks: ['qunit'], plugins: [ 'karma-qunit', 'karma-ember-preprocessor', 'karma-phantomjs-launcher' ], preprocessors: { '**/*.handlebars': 'ember' } }); };Note - the
filessection above should include all dependencies, ie- jQuery/handlebars/ember.js along with the js and handlebars files required to deploy and run your production ember.js applicationNote - when testing ember applications, it is important that karma does not try to run the tests until the ember application has finished initialization. You will need to include a small bootstrap file in the
filessection above to enforce this. Here's an example:javascript__karma__.loaded = function() {}; App.setupForTesting(); App.injectTestHelpers(); //this gate/check is required given that standard practice in Ember tests to is to call //Ember.reset() in the afterEach/tearDown for each test. Doing so, causes the application //to 're-initialize', resulting in repeated calls to the initialize function below var karma_started = false; App.initializer({ name: "run tests", initialize: function(container, application) { if (!karma_started) { karma_started = true; __karma__.start(); } } });add a simple Qunit test
javascripttest('one should equal one', function() { equal(1, 1, 'error: one did not equal one'); });run the tests with karma from the command line
bashkarma start
A simple unit / integration tested example app showing karma / qunit / ember in action can be found here
Plus 09 Codio (`docs/plus/09-codio.md`)
Codio is a web-based cloud integrated development environment that supports almost any programming language. Every project gets its individual Box: an instantly available server-side development environment with full terminal access. Unlimited panels and tabs, and a plethora of productivity features.
Customize your Codio Project
Next to the help menu you will see the "Configure" option, if you don't see it click the little arrow near the end and then select "Configure".
This opens a .codio file which you can customize and use rather than entering commands in Terminal. Replace the existing text with the text below:
{
// Configure your Run and Preview buttons here.
// Run button configuration
"commands": {
"Karma Start": "karma start --no-browsers"
"Karam Run": "karma run"
},
// Preview button configuration
"preview": {
"Karma Preview": "http://{{domain}}:8080"
}
}If you wish, you can change the port for the Karma Preview entry, but make a note of the change as you will need to include that port in the karma.config js file later.
Configuration
Edit the
karma.conf.jsand add the following:text// hostname for the server hostname: require('os').hostname() + '.codio.io',Review webserver port entry to ensure same port defined as entered in .codio file
text// web server port port: 8080,
Capture the browser manually on the local machine
You can use your local browser.
Either:
Open a Terminal window and enter
text$ karma start --no-browsers
or
- Select Karma Start from the Run menu (the 2nd from the right button).
Select
Karma Previewfrom the Preview menu (the right-hand button).Switch back into your Codio project and either:
Open a new Terminal window and enter
text$ karma run
or
- Select Karma Run from the Run menu (the 2nd from the right button).
and your test will execute
Plus 10 Teamcity (`docs/plus/10-teamcity.md`)
pageTitle: TeamCity menuTitle: TeamCity
Running Karma in your TeamCity build is as simple as adding command line build
step to perform the task. That is basically it.
Install Prerequisites
The only prerequisite is Node (with npm) installed on the agent(s) you are going to use to
run build on.
You may decide to install Karma and Karma-related packages on the agent globally to reuse the same
Karma installation by different builds.
Configure project
Add karma-teamcity-reporter as a dependency to your project:
npm i --save-dev karma-teamcity-reporterIt is also a good idea to check that you have all karma npm dependencies listed in yourpackage.json file (e.g. karma-jasmine, karma-phantomjs-launcher and so on) to have them
being installed during the build.
Create a new TeamCity build step
Add new build step to the build configuration: use Command Line runner and fill in Custom script text area. If you had decided not to install all your npm dependencies globally
add npm install at the beginning of the script. Then add command to run Karma, e.g.:
karma start --reporters teamcity --single-run --browsers PhantomJS --colors falseRunning Karma with all these options provided via command line allows to run Karma in
TeamCity build and locally in development environment (with options from configuration
file).
--- METRICS ---
- Files Extracted: 30
- Estimated Token Budget: ~30804 tokens
- Canonical Reference: https://codewiki.google/github.com/karma-runner/karma