1. 目的

使用Karma来测试React编写的应用

2. 安装环境

使用的依赖如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
babel-core
babel-loader
babel-preset-es2015
babel-preset-react
expect

jasmine
karma
karma-chrome-launcher
// karma-firefox-launcher 如果您使用Firefox来测试,应当安装上它
karma-cli
karma-jasmine
karma-sourcemap-loader
karma-webpack
react
react-addons-test-utils
react-dom

requirejs
webpack

使用npm install命令来安装它们。

在文章最后,我们的项目文件大概是这个样子:

1
2
3
4
5
6
7
8
9
10
11
├── karma.conf.js
├── package.json
├── src
│   ├── __tests__
│   │   └── index.test.js
│   ├── components
│   │   ├── __tests__
│   │   │   └── app.test.js
│   │   └── app.comp.jsx
│   └── index.jsx
└── test-main.js

3. 完善karma配置

使用karma init karma.conf.js来引导我们建立配置。

以下是我的选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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 any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome
>

What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
> src/*.jsx
>

Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string 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

接下来编辑karma.conf.js,来补充webpack, 添加测试文件等, 主要改动如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module.exports = function(config) {
config.set({
...
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],


// list of files / patterns to load in the browser
files: [
'test-main.js'
],

...
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test-main.js': [ 'webpack', 'sourcemap' ]
},

webpack: {
devtool: 'inline-source-map',
module: {
loaders: [
{ test: /\.js$/, loader: 'babel-loader?presets[]=react,presets[]=es2015'},
{ test: /\.jsx$/, loader: 'babel-loader?presets[]=react,presets[]=es2015'}
]
}
},

webpackServer: {
noInfo: true
}
})
}

注意到files和preprocessors中都提及了test-main.js这个文件,这是一个我们自定义增加的文件,我们用它来选择含有测试代码的文件。

在项目目录中添加完成文件后(我将其放在项目根目录下,如果您放在其他路径,请对应上相应的路径),修改其内容如下:

1
2
var context = require.context('./src', true, /(spec|test)\.js$/i);
context.keys().forEach(context);

这里利用了webpack的require.context功能来包括需要的测试文件,第一行中的正则表明这些文件是以spec.js或test.js结尾的, 且对大小写不敏感。

4. 添加测试文件

添加几个React文件以及测试,尽快来尝试功能吧!

添加的几个文件放在src中,目录结构可能是这个样子:

1
2
3
4
5
6
7
8
src
├── __tests__
│   └── index.test.js
├── components
│   ├── __tests__
│   │   └── app.test.js
│   └── app.comp.jsx
└── index.jsx

接着一堆代码黏贴:

index.test.js

1
2
3
4
5
describe("index.jsx", function(){
it("renders without problems", function(){
require("../index.jsx");
})
})

index.jsx

1
2
3
4
5
6
7
8
9
10
11
import React from "react"
import ReactDOM from "react-dom"
import App from "./components/app.comp.jsx"

let root = document.createElement("div")
document.body.appendChild(root)

ReactDOM.render(
<h1> Hi </h1>,
root
);

app.comp.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React from "react"

export default class App extends React.Component{
constructor(props){
super(props)
}

getNumber(){
return 3
}

render(){
return (
<div>
<h1>Hi, Karma</h1>
<h1>Hi, React</h1>
</div>

)
}
}

app.test.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React from 'react'
import TestUtils from 'react-addons-test-utils'
import expect from 'expect'
import App from '../app.comp.jsx'

describe('app.comp.jsx', function () {
var app = TestUtils.renderIntoDocument(<App />)

it('renders without problems', function () {
expect(app).toExist()
});

it("getNumber function works", function(){
expect(app.getNumber()).toEqual(3)
})
});

5. 开始测试

在终端中输入 karma startkarma start karma.conf.js, 如图所示,

测试全都正确,Great.

app.test.js中的toEqual(3)改成toEqual(4), 报错, 很好.


整个项目的示例,您可以在这里下载到。

另外水平有限,如有错误,欢迎指正.