Set up Karma with Jasmine in Create React App
This guide will use specific versions NPM packages. Please double-check that you installed the same versions to avoid installation issues!
- Install Create React App
$ npm install -g [email protected]
- Create a new React application and eject from it
$ create-react-app my-app
$ cd my-app
$ npm run eject
Press y
to confirm that you want to eject.
- Install Karma, Karma related libraries, and Babel Polyfill
$ npm i -D [email protected] [email protected] [email protected]
$ npm i -D [email protected] [email protected]
- Install Jasmine and its Karma adapter
$ npm i -D [email protected] [email protected]
- Install
react-page-object
,enzyme
, andreact-test-renderer
$ npm i -D react-page-object [email protected] [email protected]
- Modify your
package.json
scripts
to be
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "npm run karma -- --single-run",
"karma": "BABEL_ENV=development NODE_ENV=test node_modules/karma/bin/karma start config/karma.conf.js"
},
- Create a Karma configuration file
$ touch config/karma.conf.js
- Add the following to your
config/karma.conf.js
file
var path = require('path');
var testHelperPath = path.resolve('test/testHelper.js')
module.exports = function(config) {
config.set({
// use the PhantomJS browser
browsers: ['PhantomJS'],
// use Jasmine
frameworks: ['jasmine'],
// files that Karma will server to the browser
files: [
// entry file for Webpack
testHelperPath
],
// before serving test/testHelper.js to the browser
preprocessors: {
[testHelperPath]: [
// use karma-webpack to preprocess the file via webpack
'webpack',
// use karma-sourcemap-loader to utilize sourcemaps generated by webpack
'sourcemap'
]
},
// webpack configuration used by karma-webpack
webpack: {
// generate sourcemaps
devtool: 'inline-source-map',
// enzyme-specific setup
externals: {
'cheerio': 'window',
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
},
module: {
// lint JavaScript with Eslint
preLoaders: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'eslint'
}
],
// use same loaders as Create React App
loaders: [
{
exclude: [
/\.(js|jsx)$/,
/\.css$/,
/\.json$/,
],
loader: 'file',
query: {
name: 'static/media/[name].[hash:8].[ext]'
}
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel'
},
{
test: /\.css$/,
loader: 'style!css'
},
{
test: /\.json$/,
loader: 'json'
}
]
},
// relative path starts out at the src folder when importing modules
resolve: {
root: path.resolve('./src')
}
},
webpackMiddleware: {
// only output webpack error messages
stats: 'errors-only'
},
})
}
- In the application root folder, create a
test
folder and atestHelper.js
file to it.
$ mkdir test
$ touch test/testHelper.js
- Add the following to your
test/testHelper.js
file.
// polyfill PhantomJS environment
import 'babel-polyfill'
import 'whatwg-fetch'
// require all the test files in the test folder that end with Spec.js or Spec.jsx
const testsContext = require.context(".", true, /Spec.jsx?$/);
testsContext.keys().forEach(testsContext);
// output at when the test were run
console.info(`TESTS RAN AT ${new Date().toLocaleTimeString()}`);
- Create a passing test file
$ touch test/AppSpec.js
- Add the following content to
test/AppSpec.js
import Page from 'react-page-object'
import React from 'react'
import App from 'App'
describe('AppSpec', () => {
let page
beforeEach(() => {
page = new Page(<App />)
})
afterEach(() => {
page.destroy()
})
it('should pass', () => {
expect(page.content()).toMatch(/Welcome to React/)
})
})
At this point, the set up is complete! You can run all your tests once with
$ npm test
Or continuously with
$ npm run karma