UNPKG

9.69 kBMarkdownView Raw
1---
2permalink: 'testing/testing-karma.html'
3title: Testing with Karma
4section: guides
5tags:
6 - guides
7---
8
9# Testing with Karma
10
11Configuration for setting up testing with karma.
12
13> Part of [Open Web Components](https://github.com/open-wc/open-wc/): guides, tools and libraries for modern web development and web components
14
15[![CircleCI](https://circleci.com/gh/open-wc/open-wc.svg?style=shield)](https://circleci.com/gh/open-wc/open-wc)
16[![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=M2UrSFVRang2OWNuZXlWSlhVc3FUVlJtTDkxMnp6eGFDb2pNakl4bGxnbz0tLUE5RjhCU0NUT1ZWa0NuQ3MySFFWWnc9PQ==--86f7fac07cdbd01dd2b26ae84dc6c8ca49e45b50)](https://www.browserstack.com/automate/public-build/M2UrSFVRang2OWNuZXlWSlhVc3FUVlJtTDkxMnp6eGFDb2pNakl4bGxnbz0tLUE5RjhCU0NUT1ZWa0NuQ3MySFFWWnc9PQ==--86f7fac07cdbd01dd2b26ae84dc6c8ca49e45b50)
17[![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com/)
18
19We recommend karma as a general-purpose tool for testing code that runs in the browser. Karma can run a large range of browsers, including IE11. This way you are confident that your code runs correctly in all supported environments.
20
21During development you can run Chrome Headless, giving fast feedback in the terminal while writing your tests. In your CI you can run more browsers, and/or use a service like [Browserstack](https://www.browserstack.com/) or [Saucelabs](https://saucelabs.com/) for testing in all supported browsers.
22
23Karma can be used both for running unit tests, as well as for running more complex e2e/integration tests in the DOM.
24
25## Getting started
26
27Our configuration sets up karma to run tests based on es modules with the necessary polyfills and fallbacks for older browsers and convenient test reporting.
28
29This page explains how to set up `karma`, see the [testing overview](https://open-wc.org/testing/) for guides and libraries to get started with testing in general.
30
31### Features
32
33- Runs tests with es modules
34- Serves static files
35- Runs tests through mocha
36- Deep object diffs in mocha errors
37- Test coverage through instanbul when passing the `coverage` flag
38- Supports older browsers (down to IE11)
39
40## Setup
41
42With our project scaffolding you can set up a pre-configured project, or you can upgrade an existing project by choosing `Upgrade -> Testing`:
43
44```bash
45npm init @open-wc
46```
47
48### Manual
49
50Install:
51
52```bash
53npm i -D @open-wc/testing-karma deepmerge karma
54```
55
56Create a `karma.conf.js`:
57
58```js
59const { createDefaultConfig } = require('@open-wc/testing-karma');
60const merge = require('deepmerge');
61
62module.exports = config => {
63 config.set(
64 merge(createDefaultConfig(config), {
65 files: [
66 // runs all files ending with .test in the test folder,
67 // can be overwritten by passing a --grep flag. examples:
68 //
69 // npm run test -- --grep test/foo/bar.test.js
70 // npm run test -- --grep test/bar/*
71 { pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' },
72 ],
73
74 // see the karma-esm docs for all options
75 esm: {
76 // if you are using 'bare module imports' you will need this option
77 nodeResolve: true,
78 },
79 }),
80 );
81 return config;
82};
83```
84
85Add scripts to your package.json:
86
87```json
88{
89 "scripts": {
90 "test": "karma start --coverage",
91 "test:watch": "karma start --auto-watch=true --single-run=false",
92 "test:update-snapshots": "karma start --update-snapshots",
93 "test:prune-snapshots": "karma start --prune-snapshots"
94 }
95}
96```
97
98## Workflow
99
100Commands explained:
101
102- `test`: does a single test run on the configured browsers (default headless chrome) and prints tests and coverage results.
103- `test:watch`: does a single test run, and then re-runs on file changes. coverage is not analyzed for performance. in watch mode you can also visit http://localhost:9876/debug.html to debug in the browser
104- `test:update-snapshots`: updates any snapshots files from `@open-wc/semantic-dom-diff`. Use this when your component's rendered HTML changed.
105- `test:prune-snapshots`: prunes any used snapshots files from `@open-wc/semantic-dom-diff`.
106
107## Testing single files or folders
108
109By default, karma runs all your test files. To test a single file or folder, use the `--grep` flag. (If you did a manual setup, makes sure your config handles this flag).
110
111Pass which files to test to the grep flag: `npm run test -- --grep test/foo/bar.test.js`.
112
113## Debugging in the browser
114
115While testing, it can be useful to debug your tests in a real browser so that you can use the browser's dev tools.
116
117Use `npm run test:watch` to keep karma running. Then open the URL printed by karma when it boots up. By default, this is `http://localhost:9876/`. Click the debug button in the top right corner, or go directly to `http://localhost:9876/debug.html`.
118
119You can bookmark this page for easy access.
120
121Adding `debugger` statements will allow you to debug using the browser's dev tools.
122
123## Testing on older browsers
124
125Testing on older browsers is powered by es-dev-server's compatibility mode.
126
127See the [compatibility documentation of es-dev-server](https://open-wc.org/developing/es-dev-server.html#compatibility-mode) for more information.
128
129## Testing on WSL (Windows Subsystem for Linux)
130
131Currently Chrome Headless has issues on WSL.
132Until they are fixed, you can work around it by pointing your CHROME_BIN variable to your Windows installation of chrome instead of chromium inside your linux distro.
133This works because with WSL, you can use executables between environments.
134
135```bash
136export CHROME_BIN=/mnt/c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe
137```
138
139## Why don't you recommend testing tool X?
140
141Sometimes people ask why we recommend Karma and not other popular testing tools. We're always on the lookout for improving our recommendations, so if you think we can do better please let us know. What's important for us is that the testing tool is robust, simple to use, does not require any building, and runs in a real browser.
142
143Testing tools that don't use a real browser but something like JSDOM constantly need to keep up with the latest browser standards, so you need to wait for your testing tool to update before you can use a new feature. It doesn't give the same confidence as testing in a real browser, and with Headless Chrome and Puppeteer it hardly seems necessary anymore.
144
145## Extending the config
146
147To extend the karma config, we recommend using `deepmerge`. This will do smart merging of complex objects. You can extend any of the configuration. For example to set your own test coverage threshold:
148
149```js
150const { createDefaultConfig } = require('@open-wc/testing-karma');
151const merge = require('deepmerge');
152
153module.exports = config => {
154 config.set(
155 deepmerge(createDefaultConfig(config), {
156 files: [
157 // runs all files ending with .test in the test folder,
158 // can be overwritten by passing a --grep flag. examples:
159 //
160 // npm run test -- --grep test/foo/bar.test.js
161 // npm run test -- --grep test/bar/*
162 { pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' },
163 ],
164
165 coverageIstanbulReporter: {
166 thresholds: {
167 global: {
168 statements: 50,
169 lines: 50,
170 branches: 50,
171 functions: 50,
172 },
173 },
174 },
175 }),
176 );
177 return config;
178};
179```
180
181### Custom babel plugins
182
183`karma-esm` supports custom babel configurations. [Check out the documentaton](https://open-wc.org/testing/karma-esm.html) for more information.
184
185### Typescript
186
187Because `karma-esm` doesn't do any bundling, it is compatible with typescript out of the box. [Check out the documentaton](https://open-wc.org/testing/karma-esm.html) for more information.
188
189### Testing in a monorepository
190
191When testing without a bundler you will be serving every imported module straight from the file system. Karma cannot serve files outside the path of the webserver, which by default starts from the directory of your karma config.
192
193In a monorepo dependencies are often two levels higher in the root of the repository. To run tests in a monorepository you either have to put your config in the root of the repository, or adjust the basePath in your karma config:
194
195```js
196const { createDefaultConfig } = require('@open-wc/testing-karma');
197const merge = require('deepmerge');
198
199module.exports = config => {
200 config.set(
201 merge(createDefaultConfig(config), {
202 files: [{ pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' }],
203
204 basePath: '../../',
205 }),
206 );
207 return config;
208};
209```
210
211### Preserving symlinks
212
213When using a tool that relies on symlinks such as `npm link` or `lerna`, the `es-dev-server` that runs under the hood of `karma-esm` plugin needs to run with `--preserve-symlinks` option.
214
215You can pass this option via the `esm` plugin configuration:
216
217```js
218 ...
219 esm: {
220 nodeResolve: true,
221 preserveSymlinks: true,
222 },
223 ...
224```
225
226[Check out the documentaton](https://open-wc.org/testing/karma-esm.html) for more information.
227
228### Other configuration
229
230`karma-esm` is the plugin powering our configuration, and it supports a few more for advanced use cases. [Check out the documentaton](https://open-wc.org/testing/karma-esm.html) for more information.
231
232```js
233const { createDefaultConfig } = require('@open-wc/testing-karma');
234const merge = require('deepmerge');
235
236module.exports = config => {
237 config.set(
238 merge(createDefaultConfig(config), {
239 files: [{ pattern: config.grep ? config.grep : 'test/**/*.test.js', type: 'module' }],
240
241 basePath: '../../',
242 }),
243 );
244 return config;
245};
246```