本文全部资料请参考:github.com/antgod/reac…html
npm install --save-dev jest复制代码
咱们先写一个测试函数,有两个数字参数作加法,首先,建立sum.js
文件node
function sum(a, b) {
return a + b
}
module.exports = sum复制代码
而后,建立建立sum.test.js
,包含咱们目前的测试代码。react
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});复制代码
而后添加片断到package.json中android
{
"scripts": {
"test": "jest"
}
}复制代码
最后运行npm test
,jest输入以下内容webpack
PASS ./sum.test.js
✓ adds 1 + 2 to equal 3 (5ms)复制代码
你刚刚成功的编写了一个jest测试!git
这个测试用例使用了expect
和toBe
进行两个值相同的测试。想要学习更多的关于jest测试,请参考 Using Matcherses6
你也能够直接从命令行执行,能够输入一些有空的参数(npm install jest -g)。github
Here's how to run Jest on files matching my-test, using config.json as a configuration file and display a native OS notification after the run:web
jest my-test --notify --config=config.json复制代码
若是你想学习更多的命令行执行,请参考 Jest CLI Options正则表达式
使用 Babel:
安装babel-jest
和 regenerator-runtime
包:
npm install --save-dev babel-jest regenerator-runtime复制代码
注意: 若是你使用npm 3或者npm 4,你不用指明安装regenerator-runtime
。
添加一份.babelrc
文件到你的工程根目录,好比,若是你使用es6或者react.js须要使用babel-preset-es2015
和babel-preset-react
预设:
{
"presets": ["es2015", "react"]
}复制代码
这样你会使用es6与react全部指定的语法。
注意: 若是你使用更多的babel编译配置,请使用babel's env option
,记住jest将会自动定义node_env做为测试。
使用webpack
jest能够实用在工程内使用webpack管理你的资产,样式和编辑。webpack 提供一些特别的功能相比于其余工具。更多资料请参考 webpack guide
jest使用matchers
让你经过不一样的方法测试值。你须要熟记不少不一样的matchers
。这里只介绍最经常使用的matchers
。
最简单的测试值相等的是精确相等:
test('two plus two is four', () => {
expect(2 + 2).toBe(4);
});复制代码
上段代码,expect(2 + 2)
返回一个“期待”对象。除了调用matchers
,关于期待对象你不须要作太多。在这段代码中,.toBe(4)
是一个matcher。当jest运行时,将追踪全部失败的matchers
,因此它能够精确的打印错误信息。
toBe
使用===
精确等于测试。若是你想深度测试对象相等,使用toEqual
代替。
test('object assignment', () => {
const data = {one: 1};
data['two'] = 2;
expect(data).toEqual({one: 1, two: 2});
});复制代码
toEqual
递归的查找每一个字段对比是否相等。
你可使用not
去测试matcher
的反面:
test('adding positive numbers is not zero', () => {
for (let a = 1; a < 10; a++) {
for (let b = 1; b < 10; b++) {
expect(a + b).not.toBe(0);
}
}
});复制代码
有时候你须要判断undefined,null与false,但有时候你不须要明确的区分他们。jest包含工具明确的区分他们。
举个例子:
test('null', () => {
const n = null;
expect(n).toBeNull();
expect(n).toBeDefined();
expect(n).not.toBeUndefined();
expect(n).not.toBeTruthy();
expect(n).toBeFalsy();
});
test('zero', () => {
const z = 0;
expect(z).not.toBeNull();
expect(z).toBeDefined();
expect(z).not.toBeUndefined();
expect(z).not.toBeTruthy();
expect(z).toBeFalsy();
});复制代码
你可使用这些matcher
作精确的匹配。
多种途径比较数字
test('two plus two', () => {
const value = 2 + 2;
expect(value).toBeGreaterThan(3);
expect(value).toBeGreaterThanOrEqual(3.5);
expect(value).toBeLessThan(5);
expect(value).toBeLessThanOrEqual(4.5);
// toBe and toEqual are equivalent for numbers
expect(value).toBe(4);
expect(value).toEqual(4);
});复制代码
你可使用toBeCloseTo
进行浮点比较
test('adding floating point numbers', () => {
const value = 0.1 + 0.2;
expect(value).not.toBe(0.3); // 浮点数不会直接相等
expect(value).toBeCloseTo(0.3); // 使用closeTo方法进行浮点数字比较
});复制代码
你可使用toMatch
测试正则表达式来验证string字符串
test('there is no I in team', () => {
expect('team').not.toMatch(/I/);
});
test('but there is a "stop" in Christoph', () => {
expect('Christoph').toMatch(/stop/);
});复制代码
你能够检验数组是否包含某一个特别项
const shoppingList = [
'diapers',
'kleenex',
'trash bags',
'paper towels',
'beer',
];
test('the shopping list has beer on it', () => {
expect(shoppingList).toContain('beer');
});复制代码
你可使用toThrow
来检验函数是否抛出异常
function compileAndroidCode() {
throw new ConfigError('you are using the wrong JDK');
}
test('compiling android goes as expected', () => {
expect(compileAndroidCode).toThrow();
expect(compileAndroidCode).toThrow(ConfigError);
// You can also use the exact error message or a regexp
expect(compileAndroidCode).toThrow('you are using the wrong JDK');
expect(compileAndroidCode).toThrow(/JDK/);
});复制代码
这是一个just尝试,查看完整的matchers
列表renerence docs。
一旦你掌握了一个可用的matcher
,建议下一步学习jest如何检验异步代码
js运行异步代码是很广泛的。jest
须要知道何时代码测试已完成,才能移动到下一个测试。jest
有几种方法处理。
最广泛的异步是经过回调函数。
好比,若是你调用fetchData(callback)
函数去拉取异步数据而且结束时候调用callback(data)
。你要测试的数据是否等于peanut buter
。
默认状况下,Jest
走完测试代码就完成测试。这意味着测试不能定期进行。
// Don't do this!
test('the data is peanut butter', () => {
function callback(data) {
expect(data).toBe('peanut butter');
}
fetchData(callback);
});复制代码
问题在于测试工做将在fetchData
结束的时候,也就是在回调函数以前结束。
为了解决这个问题,这是另外一种形式。使用参数done
来代替无参函数。Jest
将会延迟测试直到done
回调函数执行完毕。
test('the data is peanut butter', done => {
function callback(data) {
expect(data).toBe('peanut butter');
done();
}
fetchData(callback);
});复制代码
若是done
一直没有调用,测试将会失败。
若是你使用promise,有一种简单的方法处理异步测试。你的测试代码中Jest
返回一个Promise
,而且等待Promise
去resolve
。若是Promise
是rejected
,测试自动失败。
好比,仍是那个fetchData
,此次使用了回调,返回一个promise
假定reslove
一个字符串peanut butter
。测试代码以下:
test('the data is peanut butter', () => {
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});复制代码
确保返回一个Promise-若是你省略了return
,你的测试代码将会在fetchData
以前结束。
你也可使用resolves
关键字在你的expect
代码后,而后Jest
将会把等待状态转换成resolve
。若是promise
被rejected
,测试自动失败。
test('the data is peanut butter', () => {
return expect(fetchData()).resolves.toBe('peanut butter');
});复制代码
若是你使用async/await
,你能够完美嵌入测试。写一个async
测试,仅使用async
关键字在你的matchers
函数前面就能经过测试。好比,仍是fetchData
这个测试方案能够写成
test('the data is peanut butter', async () => {
await expect(fetchData()).resolves.toBe('peanut butter');
});复制代码
在这种状况下,async/await
仅仅是个有效的promises
样例的逻辑语法糖。
这些表单特别优秀,你能够混合使用这些在你的代码库或者单个文件中,它仅仅使你的测试变得更加简单。
写测试的过程当中,在你运行测试以前,你须要作一些初始化工做,去作一些须要测试的事情以前,而且你须要作一些结束工做,去作一些测试结束的事情。Jest
提供了helper
函数去处理这些工做。
若是你有不少测试有重复的工做,你能够是使用beforeEach
与afterEach
。
好比你有不少测试运行以前须要调用initializeCityDatabase()
,并且测试结束 后须要调用clearCityDatabase()
。你能够这么作:
beforeEach(() => {
initializeCityDatabase();
});
afterEach(() => {
clearCityDatabase();
});
test('city database has Vienna', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('city database has San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});复制代码
一样的,若是你的initializeCityDatabase
函数返回一个promise
,你可使用return
返回这个函数。
beforeEach(() => {
return initializeCityDatabase();
});复制代码
若是你有不少测试有共同的重复的工做,而且重复的工做只在测试开始与测试结束的地方运行一次,你能够是使用beforeAll
与beforeAll
。
好比你有一个测试开始以前要调用initializeCityDatabase()
,并且测试结束 后须要调用clearCityDatabase()
。你能够这么作:
beforeAll(() => {
return initializeCityDatabase();
});
afterAll(() => {
return clearCityDatabase();
});
test('city database has Vienna', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('city database has San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});复制代码
默认状况下,before
与after
会对文件的每一个测试生效。若是你只想对某些测试生效,你可使用describe
块。 before
与after
仅仅会在声明块中运行。
好比,咱们不只须要城市初始化,还须要食物初始化,咱们能够对不一样的测试作不一样的初始化。
// Applies to all tests in this file
beforeEach(() => {
return initializeCityDatabase();
});
test('city database has Vienna', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('city database has San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});
describe('matching cities to foods', () => {
// Applies only to tests in this describe block
beforeEach(() => {
return initializeFoodDatabase();
});
test('Vienna <3 sausage',="" ()=""> {
expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true);
});
test('San Juan <3 plantains',="" ()=""> {
expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
});
});
复制代码
若是你仅仅想测试一个测试用例,或者跨过某个测试用例,你可使用fit
与xit
。
fit('this will be the only test that runs', () => {
expect(true).toBe(false);
});
xit('this will be the only test that runs', () => {
expect(true).toBe(false);
});
test('this test will not run', () => {
expect('A').toBe('A');
});复制代码