全局设定
Jest会将这些方法和对象注入到测试文件的全局环境里, 所以你在使用的时候不再需要进行require或者import。 如果你习惯编写明确的导入,你可以在测试文件顶部添加 import {describe, expect, test} from '@jest/globals'
。
方法
afterAll(fn, timeout)
afterEach(fn, timeout)
beforeAll(fn, timeout)
beforeEach(fn, timeout)
describe(name, fn)
describe.each(table)(name, fn, timeout)
describe.only(name, fn)
describe.only.each(table)(name, fn)
describe.skip(name, fn)
describe.skip.each(table)(name, fn)
test(name, fn, timeout)
test.each(table)(name, fn, timeout)
1. test.only(name, fn, timeout)
test.only.each(table)(name, fn)
test.skip(name, fn)
test.skip.each(table)(name, fn)
test.todo(name)
参考
afterAll(fn, timeout)
文件内所有测试完成后执行的钩子函数。 如果传入的回调函数返回值是 promise 或者 generator,Jest 会等待 promise resolve 再继续执行。
可选地传入第二个参数 timeout(毫秒) 指定函数执行超时时间。 The default timeout is 5 seconds.
使用 afterAll 非常方便你清理一些在测试用例之间共享的全局状态。
例如:
const globalDatabase = makeGlobalDatabase();
function cleanUpDatabase(db) {
db.cleanUp();
}
afterAll(() => {
cleanUpDatabase(globalDatabase);
});
test('can find things', () => {
return globalDatabase.find('thing', {}, results => {
expect(results.length).toBeGreaterThan(0);
});
});
test('can insert a thing', () => {
return globalDatabase.insert('thing', makeThing(), response => {
expect(response.success).toBeTruthy();
});
});
上述代码中 afterAll
确保了全部测试完成后调用 cleanUpDatabase
完成清理操作。
如果 afterAll
定义在 describe
块的内部,它将会在 describe 块结束时执行。
如果你想每个测试完成时都运行一遍钩子,请使用 afterEach
afterEach(fn, timeout)
文件内每个测试完成后执行的钩子函数。 如果传入的回调函数返回值是 promise 或者 generator,Jest 会等待 promise resolve 再继续执行。
可选地传入第二个参数 timeout(毫秒) 指定函数执行超时时间。 The default timeout is 5 seconds.
使用 afterEach 会非常方便你清理一些在每个测试中创建的临时状态。
例如:
const globalDatabase = makeGlobalDatabase();
function cleanUpDatabase(db) {
db.cleanUp();
}
afterEach(() => {
cleanUpDatabase(globalDatabase);
});
test('can find things', () => {
return globalDatabase.find('thing', {}, results => {
expect(results.length).toBeGreaterThan(0);
});
});
test('can insert a thing', () => {
return globalDatabase.insert('thing', makeThing(), response => {
expect(response.success).toBeTruthy();
});
});
上述代码中,afterEach
确保了每一次测试结束后都调用一次 cleanUpDatabase
。
如果 afterEach
定义在 describe
块的内部,它会在该 describe 块内的每一个测试结束时执行。
如果你只想在所有测试完成后执行一遍钩子,请使用 afterAll
。
beforeAll(fn, timeout)
文件内所有测试开始前执行的钩子函数。 如果传入的回调函数返回值是 promise 或者 generator,Jest 会等待 promise resolve 再继续执行。
可选地传入第二个参数 timeout(毫秒) 指定函数执行超时时间。 The default timeout is 5 seconds.
使用 beforeAll 会非常方便你设置一些在测试用例之间共享的全局状态。
例如:
const globalDatabase = makeGlobalDatabase();
beforeAll(() => {
// 清空数据库并添加几条数据
// Jest 会等待 promise resolve 再去执行测试
return globalDatabase.clear().then(() => {
return globalDatabase.insert({testData: 'foo'});
});
});
// 因为我们在开始前设置了一个全局共享的数据库
// 所以我们测试时不能修改数据库的数据
test('can find things', () => {
return globalDatabase.find('thing', {}, results => {
expect(results.length).toBeGreaterThan(0);
});
});
上述代码中 beforeAll
确保在所有测试运行之前完成数据库的初始化操作。 如果初始化操作是同步的,你可以不用 beforeAll
直接执行。 关键是 Jest 会等待 promise resolve,所以可以进行异步的初始化操作。
如果 beforeAll
定义在 describe
块的内部,它将会在 describe 块开始前执行。
如果要在每次测试开始之前执行某些操作,而不是在每次测试开始之前执行,请使用beforeEach
。
beforeEach(fn, timeout)
文件内每个测试开始前执行的钩子函数。 如果传入的回调函数返回值是 promise 或者 generator,Jest 会等待 promise resolve 再继续执行测试。
可选地传入第二个参数 timeout(毫秒) 指定函数执行超时时间。 The default timeout is 5 seconds.
使用 beforeEach 非常方便你重新设置一些全局状态在每个测试开始前。
例如:
const globalDatabase = makeGlobalDatabase();
beforeEach(() => {
// Clears the database and adds some testing data.
// Jest 会等待 promise resolve 再去执行测试
return globalDatabase.clear().then(() => {
return globalDatabase.insert({testData: 'foo'});
});
});
test('can find things', () => {
return globalDatabase.find('thing', {}, results => {
expect(results.length).toBeGreaterThan(0);
});
});
test('can insert a thing', () => {
return globalDatabase.insert('thing', makeThing(), response => {
expect(response.success).toBeTruthy();
});
});
上述代码中 beforeEach
确保了每个测试开始前会重置数据库数据。
如果 beforeEach
定义在 describe
块内,它将会在该 describe
块内的每个测试运行之前执行。
如果你需要在运行所有测试之前执行一些初始化代码, 请使用 beforeAll
。
describe(name, fn)
describe(name, fn)
是一个将多个相关的测试组合在一起的块。 比如,现在有一个myBeverage
对象,描述了某种饮料好喝但是不酸,通过以下方式测试:
const myBeverage = {
delicious: true,
sour: false,
};
describe('my beverage', () => {
test('is delicious', () => {
expect(myBeverage.delicious).toBeTruthy();
});
test('is not sour', () => {
expect(myBeverage.sour).toBeFalsy();
});
});
注意:这不是强制的,你甚至可以直接把 test
块直接写在最外层。 但是如果你习惯按组编写测试,使用 describe
包裹相关测试用例更加友好。
如果你有多层级的测试,你也可以嵌套使用 describe
块:
const binaryStringToNumber = binString => {
if (!/^[01]+$/.test(binString)) {
throw new CustomError('Not a binary number.');
}
return parseInt(binString, 2);
};
describe('binaryStringToNumber', () => {
describe('given an invalid binary string', () => {
test('composed of non-numbers throws CustomError', () => {
expect(() => binaryStringToNumber('abc')).toThrow(CustomError);
});
test('with extra whitespace throws CustomError', () => {
expect(() => binaryStringToNumber(' 100')).toThrow(CustomError);
});
});
describe('given a valid binary string', () => {
test('returns the correct number', () => {
expect(binaryStringToNumber('100')).toBe(4);
});
});
});
describe.each(table)(name, fn, timeout)
describe.each
可以用多组测试数据去测试同一测试用例。 这样你就可以只用编写一次测试代码。
describe.each
有两种使用方式:
1. describe.each(table)(name, fn, timeout)
table
:数组类型
。table里的数据将按照顺序作为参数传给 fn 函数 If you pass in a 1D array of primitives, internally it will be mapped to a table i.e.[1, 2, 3] -> [[1], [2], [3]]
.name
:字符串类型
,代表测试套件的标题- 根据注入参数的位置生成相应的测试标题,参考
printf
formatting:%p
- pretty-format.%s
- String.%d
- Number.%i
- Integer.%f
- Floating point value.%j
- JSON.%o
- Object.%#
- 测试用例的顺序编号%%
- 单个百分比符号 ('%'). 它不使用参数。
- 根据注入参数的位置生成相应的测试标题,参考
fn
:Function
the suite of tests to be run, this is the function that will receive the parameters in each row as function arguments.可选地传入第三个参数
timeout
(毫秒)指定该测试套件每次运行的最长时间。 The default timeout is 5 seconds.
示例:
describe.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected);
});
test(`returned value not be greater than ${expected}`, () => {
expect(a + b).not.toBeGreaterThan(expected);
});
test(`returned value not be less than ${expected}`, () => {
expect(a + b).not.toBeLessThan(expected);
});
});
2. describe.each`table`(name, fn, timeout)
table
:Tagged Template Literal
- First row of variable name column headings separated with
|
- One or more subsequent rows of data supplied as template literal expressions using
${value}
syntax.
- First row of variable name column headings separated with
name
:字符串
the title of the test suite, use$variable
to inject test data into the suite title from the tagged template expressions.- To inject nested object values use you can supply a keyPath i.e.
$variable.path.to.value
- To inject nested object values use you can supply a keyPath i.e.
fn
:Function
the suite of tests to be run, this is the function that will receive the test data object.- 可选地传入第三个参数
timeout
(毫秒)指定该测试套件每次运行的最长时间。 The default timeout is 5 seconds.
示例:
describe.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('$a + $b', ({a, b, expected}) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected);
});
test(`returned value not be greater than ${expected}`, () => {
expect(a + b).not.toBeGreaterThan(expected);
});
test(`returned value not be less than ${expected}`, () => {
expect(a + b).not.toBeLessThan(expected);
});
});
describe.only(name, fn)
别名:fdescribe(name, fn)
运行某个指定的describe
块,你可以使用 describe.only
:
describe.only('my beverage', () => {
test('is delicious', () => {
expect(myBeverage.delicious).toBeTruthy();
});
test('is not sour', () => {
expect(myBeverage.sour).toBeFalsy();
});
});
describe('my other beverage', () => {
// ... will be skipped
});
describe.only.each(table)(name, fn)
别名: fdescribe.each(table)(name, fn)
或 fit(name, fn)
用多组数组测试某个特定的测试套件,使用 describe.only.each
describe.only.each
有两种使用方式:
describe.only.each(table)(name, fn)
describe.only.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected);
});
});
test('will not be run', () => {
expect(1 / 0).toBe(Infinity);
});
describe.only.each`table`(name, fn)
describe.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added to $b', ({a, b, expected}) => {
test('passes', () => {
expect(a + b).toBe(expected);
});
});
test('will not be run', () => {
expect(1 / 0).toBe(Infinity);
});
describe.skip(name, fn)
别名:xdescribe(name, fn)
如果想跳过特定的 describe
块,可以使用describe.skip
:
describe('my beverage', () => {
test('is delicious', () => {
expect(myBeverage.delicious).toBeTruthy();
});
test('is not sour', () => {
expect(myBeverage.sour).toBeFalsy();
});
});
describe.skip('my other beverage', () => {
// ... will be skipped
});
describe.skip
常用于代替注释掉用例,这样做更显干净。 请注意, describe
块仍会运行。 如果有同样要跳过的初始化代码,请放在 beforeAll
或 beforeEach
内。
describe.skip.each(table)(name, fn)
别名: xdescribe.each(table)(name, fn)
或 fit(name, fn)
跳过用多组数组测试某个特定的测试套件,使用 describe.skip.each
describe.skip.each
有两种使用方式:
describe.skip.each(table)(name, fn)
describe.skip.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
test(`returns ${expected}`, () => {
expect(a + b).toBe(expected); // will not be run
});
});
test('will be run', () => {
expect(1 / 0).toBe(Infinity);
});
describe.skip.each`table`(name, fn)
describe.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added to $b', ({a, b, expected}) => {
test('will not be run', () => {
expect(a + b).toBe(expected); // will not be run
});
});
test('will be run', () => {
expect(1 / 0).toBe(Infinity);
});
test(name, fn, timeout)
别名:it(name, fn, timeout)
test
是将运行测试的方法。 例如,现在有一个函数inchesOfRain()
,返回值应该为零。 你的整个测试可能是:
test('did not rain', () => {
expect(inchesOfRain()).toBe(0);
});
第一个参数是测试名称; 第二个参数是包含测试期望的函数。 可选地传入第三个参数 timeout(毫秒) 指定测试超时时间。 The default timeout is 5 seconds.
If a promise is returned from test
, Jest will wait for the promise to resolve before letting the test complete. 例如,假设fetchBeverageList()
返回一个应该解析为具有lemon
的列表的承诺。 You can test this with:
test('has lemon in it', () => {
return fetchBeverageList().then(list => {
expect(list).toContain('lemon');
});
});
Even though the call to test
will return right away, the test doesn't complete until the promise resolves. For more details, see Testing Asynchronous Code page.
Jest will also wait if you provide an argument to the test function, usually called done
. This could be handy when you want to test callbacks.
test.each(table)(name, fn, timeout)
别名: it.each(table)(name, fn)
和 it.each`table`(name, fn)
Use test.each
if you keep duplicating the same test with different data. test.each
allows you to write the test once and pass data in. test.each
allows you to write the test once and pass data in.
test.each
is available with two APIs:
1. test.each(table)(name, fn, timeout)
table
:数组
of Arrays with the arguments that are passed into the testfn
for each row. If you pass in a 1D array of primitives, internally it will be mapped to a table i.e.[1, 2, 3] -> [[1], [2], [3]]
name
:字符串
the title of the test block.- 根据注入参数的位置生成相应的测试标题,参考
printf
formatting:%p
- pretty-format.%s
- String.%d
- Number.%i
- Integer.%f
- Floating point value.%j
- JSON.%o
- Object.%#
- 测试用例的顺序编号%%
- 单个百分比符号 ('%'). 它不使用参数。
- 根据注入参数的位置生成相应的测试标题,参考
fn
:Function
the test to be run, this is the function that will receive the parameters in each row as function arguments.- 可选地传入第三个参数
timeout
(毫秒)指定该测试套件每次运行的最长时间。 The default timeout is 5 seconds.
示例:
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
expect(a + b).toBe(expected);
});
2. test.each`table`(name, fn, timeout)
table
:Tagged Template Literal
- First row of variable name column headings separated with
|
- One or more subsequent rows of data supplied as template literal expressions using
${value}
syntax.
- First row of variable name column headings separated with
name
:字符串
the title of the test, use$variable
to inject test data into the test title from the tagged template expressions.- To inject nested object values use you can supply a keyPath i.e.
$variable.path.to.value
- To inject nested object values use you can supply a keyPath i.e.
fn
:Function
the test to be run, this is the function that will receive the test data object.- 可选地传入第三个参数
timeout
(毫秒)指定该测试套件每次运行的最长时间。 The default timeout is 5 seconds.
示例:
test.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added to $b', ({a, b, expected}) => {
expect(a + b).toBe(expected);
});
1. test.only(name, fn, timeout)
Also under the aliases: it.only(name, fn, timeout)
, and fit(name, fn, timeout)
当你维护一个很大的代码库时,有时可能会发现一个由于某种原因被暂时破坏的测试。 If you want to skip running this test, but you don't want to delete this code, you can use test.skip
to specify some tests to skip.
可选地传入第二个参数 timeout(毫秒) 指定函数执行超时时间。 The default timeout is 5 seconds.
比如说,你有这些测试︰
test.only('it is raining', () => {
expect(inchesOfRain()).toBeGreaterThan(0);
});
test('it is not snowing', () => {
expect(inchesOfSnow()).toBe(0);
});
Only the "it is raining" test will run in that test file, since it is run with test.only
.
Usually you wouldn't check code using test.only
into source control - you would use it for debugging, and remove it once you have fixed the broken tests.
test.only.each(table)(name, fn)
Also under the aliases: it.only.each(table)(name, fn)
, fit.each(table)(name, fn)
, it.only.each`table`(name, fn)
and fit.each`table`(name, fn)
Use test.only.each
if you want to only run specific tests with different test data.
test.only.each
is available with two APIs:
test.only.each(table)(name, fn)
test.only.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
expect(a + b).toBe(expected);
});
test('will not be run', () => {
expect(1 / 0).toBe(Infinity);
});
test.only.each`table`(name, fn)
test.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added to $b', ({a, b, expected}) => {
expect(a + b).toBe(expected);
});
test('will not be run', () => {
expect(1 / 0).toBe(Infinity);
});
test.skip(name, fn)
Also under the aliases: it.skip(name, fn)
, xit(name, fn)
, and xtest(name, fn)
当你维护一个很大的代码库时,有时可能会发现某个测试,会因某些原因而暂时失败。 如果你想跳过运行这个测试,但你不想删除这个代码,你可以使用test.skip
来指定一些要跳过的测试。
比如说,你有这些测试︰
test('it is raining', () => {
expect(inchesOfRain()).toBeGreaterThan(0);
});
test.skip('it is not snowing', () => {
expect(inchesOfSnow()).toBe(0);
});
When you are debugging a large test file, you will often only want to run a subset of tests. You can use .only
to specify which tests are the only ones you want to run in that test file.
您可以简单地注释测试,但使用 test.skip
通常会更好一点,因为它将保留缩进和语法高亮。
test.skip.each(table)(name, fn)
Also under the aliases: it.skip.each(table)(name, fn)
, xit.each(table)(name, fn)
, xtest.each(table)(name, fn)
, it.skip.each`table`(name, fn)
, xit.each`table`(name, fn)
and xtest.each`table`(name, fn)
Use test.skip.each
if you want to stop running a collection of data driven tests.
test.skip.each
is available with two APIs:
test.skip.each(table)(name, fn)
test.skip.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
expect(a + b).toBe(expected); // will not be run
});
test('will be run', () => {
expect(1 / 0).toBe(Infinity);
});
test.skip.each`table`(name, fn)
test.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added to $b', ({a, b, expected}) => {
expect(a + b).toBe(expected); // will not be run
});
test('will be run', () => {
expect(1 / 0).toBe(Infinity);
});
test.todo(name)
Also under the alias: it.todo(name)
用 test.todo
来表示你计划要写这些测试。 Use test.todo
when you are planning on writing tests. These tests will be highlighted in the summary output at the end so you know how many tests you still need todo.
const add = (a, b) => a + b;
test.todo('add should be associative');
test.todo
will throw an error if you pass it a test callback function. Use test.skip
instead, if you already implemented the test, but do not want it to run.