全局变量
在你的测试文件中,Jest 将每个方法和对象放入全局环境中。 你无需要求或导入任何内容即可使用它们。 但是,如果你更喜欢显式导入,则可以执行 import {describe, expect, test} from '@jest/globals'
。
仅当你显式导入 Jest API 时,此页面中的 TypeScript 示例才会按照文档说明的方式工作:
import {expect, jest, test} from '@jest/globals';
有关如何使用 TypeScript 设置 Jest 的详细信息,请参阅 入门 指南。
方法
- 参考
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.concurrent(name, fn, timeout)
test.concurrent.each(table)(name, fn, timeout)
test.concurrent.only.each(table)(name, fn)
test.concurrent.skip.each(table)(name, fn)
test.each(table)(name, fn, timeout)
test.failing(name, fn, timeout)
test.failing.each(name, fn, timeout)
test.only.failing(name, fn, timeout)
test.skip.failing(name, fn, timeout)
test.only(name, fn, timeout)
test.only.each(table)(name, fn)
test.skip(name, fn)
test.skip.each(table)(name, fn)
test.todo(name)
- TypeScript 用法
参考
afterAll(fn, timeout)
该文件中的所有测试完成后运行函数。 如果函数返回一个 Promise 或者是一个生成器,Jest 会等待该 Promise 解析后再继续。
或者,你可以提供 timeout
(以毫秒为单位)来指定中止之前等待的时间。 默认超时为 5 秒。
如果你想要清理跨测试共享的某些全局设置状态,这通常很有用。
例如:
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
块内,则它在描述块的末尾运行。
如果你想在每次测试后而不是在所有测试后运行一些清理,请改用 afterEach
。
afterEach(fn, timeout)
此文件中的每一项测试完成后运行一个函数。 如果函数返回一个 Promise 或者是一个生成器,Jest 会等待该 Promise 解析后再继续。
或者,你可以提供 timeout
(以毫秒为单位)来指定中止之前等待的时间。 默认超时为 5 秒。
如果你想要清理每个测试创建的一些临时状态,这通常很有用。
例如:
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
块内,则它仅在该描述块内的测试之后运行。
如果你只想在所有测试运行后运行一次清理操作,请改用 afterAll
。
beforeAll(fn, timeout)
在运行此文件中的任何测试之前运行一个函数。 如果函数返回一个 Promise 或者是一个生成器,Jest 会在运行测试之前等待该 Promise 解析。
或者,你可以提供 timeout
(以毫秒为单位)来指定中止之前等待的时间。 默认超时为 5 秒。
如果你想设置一些将由许多测试使用的全局状态,这通常很有用。
例如:
const globalDatabase = makeGlobalDatabase();
beforeAll(() => {
// Clears the database and adds some testing data.
// Jest will wait for this promise to resolve before running tests.
return globalDatabase.clear().then(() => {
return globalDatabase.insert({testData: 'foo'});
});
});
// Since we only set up the database once in this example, it's important
// that our tests don't modify it.
test('can find things', () => {
return globalDatabase.find('thing', {}, results => {
expect(results.length).toBeGreaterThan(0);
});
});
这里,beforeAll
确保在测试运行之前设置数据库。 如果设置是同步的,你可以在没有 beforeAll
的情况下执行此操作。 关键是 Jest 将等待 promise 解决,因此你也可以进行异步设置。
如果 beforeAll
在 describe
块内,则它在描述块的开头运行。
如果你想在每个测试之前而不是任何测试运行之前运行某些内容,请改用 beforeEach
。
beforeEach(fn, timeout)
在运行此文件中的每个测试之前运行一个函数。 如果函数返回一个 Promise 或者是一个生成器,Jest 会在运行测试之前等待该 Promise 解析。
或者,你可以提供 timeout
(以毫秒为单位)来指定中止之前等待的时间。 默认超时为 5 秒。
如果你想重置许多测试将使用的某些全局状态,这通常很有用。
例如:
const globalDatabase = makeGlobalDatabase();
beforeEach(() => {
// Clears the database and adds some testing data.
// Jest will wait for this promise to resolve before running tests.
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
块内,则它针对描述块中的每个测试运行。
如果你只需要在运行任何测试之前运行一些设置代码一次,请改用 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
块:
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
允许你编写一次测试套件并传入数据。
describe.each
有两个 API:
1. describe.each(table)(name, fn, timeout)
-
table
: 数组的Array
以及每行传递到fn
中的参数。 如果你传入一个一维基元数组,它将在内部映射到一个表,即[1, 2, 3] -> [[1], [2], [3]]
。 -
name
:String
测试套件的标题。- 通过使用
printf
格式 按位置注入参数来生成唯一的测试标题:%p
- pretty-format。%s
-字符串。%d
-编号。%i
- 整数。%f
- 浮点值。%j
- JSON。%o
- 目的。%#
- 测试用例的索引。%%
- 单个百分号('%')。 这不会消耗参数。
- 或者通过使用
$variable
注入测试用例对象的属性来生成唯一的测试标题- 要注入嵌套对象值,你可以提供一个 keyPath,即
$variable.path.to.value
- 你可以使用
$#
注入测试用例的索引 - 除
%%
之外,不能将$variable
与printf
格式一起使用
- 要注入嵌套对象值,你可以提供一个 keyPath,即
- 通过使用
-
fn
:Function
要运行的测试套件,这是将接收每行中的参数作为函数参数的函数。 -
或者,你可以提供
timeout
(以毫秒为单位)来指定中止之前等待每行的时间。 默认超时为 5 秒。
例子:
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);
});
});
describe.each([
{a: 1, b: 1, expected: 2},
{a: 1, b: 2, expected: 3},
{a: 2, b: 1, expected: 3},
])('.add($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);
});
});
2. describe.each`table`(name, fn, timeout)
table
:Tagged Template Literal
- 第一行变量名称列标题以
|
分隔 - 使用
${value}
语法作为模板字面量表达式提供的一行或多行后续数据。
- 第一行变量名称列标题以
name
:String
是测试套件的标题,使用$variable
将测试数据从标记的模板表达式注入到套件标题中,$#
是行的索引。- 要注入嵌套对象值,你可以提供一个 keyPath,即
$variable.path.to.value
- 要注入嵌套对象值,你可以提供一个 keyPath,即
fn
:Function
要运行的测试套件,这是将接收测试数据对象的函数。- 或者,你可以提供
timeout
(以毫秒为单位)来指定中止之前等待每行的时间。 默认超时为 5 秒。
例子:
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.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)
和 fdescribe.each`table`(name, fn)
如果你只想运行数据驱动测试的特定测试套件,请使用 describe.only.each
。
describe.only.each
有两个 API:
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)
和 xdescribe.each`table`(name, fn)
如果你想停止运行一套数据驱动测试,请使用 describe.skip.each
。
describe.skip.each
有两个 API:
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
(以毫秒为单位),用于指定中止之前等待的时间。 默认超时为 5 秒。
如果 promise 已返回 来自 test
,Jest 将等待 Promise 解决后再让测试完成。 例如,假设 fetchBeverageList()
返回一个 promise,该 promise 应该解析为其中包含 lemon
的列表。 你可以使用以下方法进行测试:
test('has lemon in it', () => {
return fetchBeverageList().then(list => {
expect(list).toContain('lemon');
});
});
尽管对 test
的调用将立即返回,但在 promise 解决之前测试不会完成。 欲了解更多详情,请参阅 测试异步代码 页。
如果你 为测试函数提供一个参数,Jest 也会等,通常称为 done
。 当你想要测试 callbacks 时,这可能会很方便。
test.concurrent(name, fn, timeout)
也在别名下: it.concurrent(name, fn, timeout)
test.concurrent
被认为是实验性的 - 有关缺失功能和其他问题的详细信息,请参阅 此处。
如果你希望测试同时运行,请使用 test.concurrent
。
第一个参数是测试名称; 第二个参数是一个异步函数,其中包含要测试的期望。 第三个参数(可选)是 timeout
(以毫秒为单位),用于指定中止之前等待的时间。 默认超时为 5 秒。
test.concurrent('addition of 2 numbers', async () => {
expect(5 + 3).toBe(8);
});
test.concurrent('subtraction 2 numbers', async () => {
expect(5 - 3).toBe(2);
});
使用 maxConcurrency
配置选项可防止 Jest 同时执行超过指定数量的测试。
test.concurrent.each(table)(name, fn, timeout)
也在别名下: it.concurrent.each(table)(name, fn, timeout)
如果你不断使用不同的数据重复相同的测试,请使用 test.concurrent.each
。 test.each
允许你编写一次测试并传入数据,测试全部异步运行。
test.concurrent.each
有两个 API:
1. test.concurrent.each(table)(name, fn, timeout)
table
: 数组的Array
以及传递到每行测试fn
中的参数。 如果你传入一个一维基元数组,它将在内部映射到一个表,即[1, 2, 3] -> [[1], [2], [3]]
name
:String
测试块的标题。- 通过使用
printf
格式 按位置注入参数来生成唯一的测试标题:%p
- pretty-format。%s
-字符串。%d
-编号。%i
- 整数。%f
- 浮点值。%j
- JSON。%o
- 目的。%#
- 测试用例的索引。%%
- 单个百分号('%')。 这不会消耗参数。
- 通过使用
fn
:Function
要运行的测试,这是将接收每行中的参数作为函数参数的函数,这必须是一个异步函数。- 或者,你可以提供
timeout
(以毫秒为单位)来指定中止之前等待每行的时间。 默认超时为 5 秒。
例子:
test.concurrent.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', async (a, b, expected) => {
expect(a + b).toBe(expected);
});
2. test.concurrent.each`table`(name, fn, timeout)
table
:Tagged Template Literal
- 第一行变量名称列标题以
|
分隔 - 使用
${value}
语法作为模板字面量表达式提供的一行或多行后续数据。
- 第一行变量名称列标题以
name
:String
测试的标题,使用$variable
将测试数据从标记的模板表达式注入到测试标题中。- 要注入嵌套对象值,你可以提供一个 keyPath,即
$variable.path.to.value
- 要注入嵌套对象值,你可以提供一个 keyPath,即
fn
:Function
要运行的测试,这是将接收测试数据对象 这必须是一个异步函数 的函数。- 或者,你可以提供
timeout
(以毫秒为单位)来指定中止之前等待每行的时间。 默认超时为 5 秒。
例子:
test.concurrent.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added to $b', async ({a, b, expected}) => {
expect(a + b).toBe(expected);
});
test.concurrent.only.each(table)(name, fn)
也在别名下: it.concurrent.only.each(table)(name, fn)
如果你只想同时运行具有不同测试数据的特定测试,请使用 test.concurrent.only.each
。
test.concurrent.only.each
有两个 API:
test.concurrent.only.each(table)(name, fn)
test.concurrent.only.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', async (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.concurrent.only.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added to $b', async ({a, b, expected}) => {
expect(a + b).toBe(expected);
});
test('will not be run', () => {
expect(1 / 0).toBe(Infinity);
});
test.concurrent.skip.each(table)(name, fn)
也在别名下: it.concurrent.skip.each(table)(name, fn)
如果你想停止运行异步数据驱动测试的集合,请使用 test.concurrent.skip.each
。
test.concurrent.skip.each
有两个 API:
test.concurrent.skip.each(table)(name, fn)
test.concurrent.skip.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', async (a, b, expected) => {
expect(a + b).toBe(expected); // will not be run
});
test('will be run', () => {
expect(1 / 0).toBe(Infinity);
});
test.concurrent.skip.each`table`(name, fn)
test.concurrent.skip.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('returns $expected when $a is added to $b', async ({a, b, expected}) => {
expect(a + b).toBe(expected); // will not be run
});
test('will be run', () => {
expect(1 / 0).toBe(Infinity);
});
test.each(table)(name, fn, timeout)
也在别名下: it.each(table)(name, fn)
和 it.each`table`(name, fn)
如果你不断使用不同的数据重复相同的测试,请使用 test.each
。 test.each
允许你编写一次测试并传入数据。
test.each
有两个 API:
1. test.each(table)(name, fn, timeout)
table
: 数组的Array
以及传递到每行测试fn
中的参数。 如果你传入一个一维基元数组,它将在内部映射到一个表,即[1, 2, 3] -> [[1], [2], [3]]
name
:String
测试块的标题。- 通过使用
printf
格式 按位置注入参数来生成唯一的测试标题:%p
- pretty-format。%s
-字符串。%d
-编号。%i
- 整数。%f
- 浮点值。%j
- JSON。%o
- 目的。%#
- 测试用例的索引。%%
- 单个百分号('%')。 这不会消耗参数。
- 或者通过使用
$variable
注入测试用例对象的属性来生成唯一的测试标题- 要注入嵌套对象值,你可以提供一个 keyPath,即
$variable.path.to.value
- 你可以使用
$#
注入测试用例的索引 - 除
%%
之外,不能将$variable
与printf
格式一起使用
- 要注入嵌套对象值,你可以提供一个 keyPath,即
- 通过使用
fn
:Function
要运行的测试,这是将接收每行中的参数作为函数参数的函数。- 或者,你可以提供
timeout
(以毫秒为单位)来指定中止之前等待每行的时间。 默认超时为 5 秒。
例子:
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
expect(a + b).toBe(expected);
});
test.each([
{a: 1, b: 1, expected: 2},
{a: 1, b: 2, expected: 3},
{a: 2, b: 1, expected: 3},
])('.add($a, $b)', ({a, b, expected}) => {
expect(a + b).toBe(expected);
});
2. test.each`table`(name, fn, timeout)
table
:Tagged Template Literal
- 第一行变量名称列标题以
|
分隔 - 使用
${value}
语法作为模板字面量表达式提供的一行或多行后续数据。
- 第一行变量名称列标题以
name
:String
测试的标题,使用$variable
将测试数据从标记的模板表达式注入到测试标题中。- 要注入嵌套对象值,你可以提供一个 keyPath,即
$variable.path.to.value
- 要注入嵌套对象值,你可以提供一个 keyPath,即
fn
:Function
要运行的测试,这是将接收测试数据对象的函数。- 或者,你可以提供
timeout
(以毫秒为单位)来指定中止之前等待每行的时间。 默认超时为 5 秒。
例子:
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);
});
test.failing(name, fn, timeout)
也在别名下: it.failing(name, fn, timeout)
这仅适用于默认的 jest-circus 运行器。
当你编写测试并预计它会失败时,请使用 test.failing
。 这些测试的行为方式与正常测试的行为方式不同。 如果 failing
测试抛出任何错误,那么它将通过。 如果不抛出就会失败。
你可以使用这种类型的测试,即以 BDD 方式编写代码时。 在这种情况下,测试在通过之前不会显示为失败。 然后你只需删除 failing
修饰符即可让它们通过。
即使你不知道如何修复错误,它也可能是向项目贡献失败测试的好方法。
例子:
test.failing('it is not equal', () => {
expect(5).toBe(6); // this test will pass
});
test.failing('it is equal', () => {
expect(10).toBe(10); // this test will fail
});
test.failing.each(name, fn, timeout)
也在别名下: it.failing.each(table)(name, fn)
和 it.failing.each`table`(name, fn)
这仅适用于默认的 jest-circus 运行器。
你还可以通过在 failing
之后添加 each
来一次运行多个测试。
例子:
test.failing.each([
{a: 1, b: 1, expected: 2},
{a: 1, b: 2, expected: 3},
{a: 2, b: 1, expected: 3},
])('.add($a, $b)', ({a, b, expected}) => {
expect(a + b).toBe(expected);
});
test.only.failing(name, fn, timeout)
也在别名下: it.only.failing(name, fn, timeout)
、fit.failing(name, fn, timeout)
这仅适用于默认的 jest-circus 运行器。
如果你只想运行特定的失败测试,请使用 test.only.failing
。
test.skip.failing(name, fn, timeout)
也在别名下: it.skip.failing(name, fn, timeout)
、xit.failing(name, fn, timeout)
、xtest.failing(name, fn, timeout)
这仅适用于默认的 jest-circus 运行器。
如果你想跳过运行特定的失败测试,请使用 test.skip.failing
。
test.only(name, fn, timeout)
也在别名下: it.only(name, fn, timeout)
和 fit(name, fn, timeout)
当你调试大型测试文件时,你通常只想运行测试的子集。 你可以使用 .only
指定你只想在该测试文件中运行哪些测试。
或者,你可以提供 timeout
(以毫秒为单位)来指定中止之前等待的时间。 默认超时为 5 秒。
例如,假设你进行了以下测试:
test.only('it is raining', () => {
expect(inchesOfRain()).toBeGreaterThan(0);
});
test('it is not snowing', () => {
expect(inchesOfSnow()).toBe(0);
});
只有 "正在下雨" 测试将在该测试文件中运行,因为它是与 test.only
一起运行的。
通常,你不会使用 test.only
将代码检查到源代码管理中 - 你会使用它进行调试,并在修复了损坏的测试后将其删除。
test.only.each(table)(name, fn)
也在别名下: it.only.each(table)(name, fn)
、fit.each(table)(name, fn)
、it.only.each`table`(name, fn)
和 fit.each`table`(name, fn)
如果你只想使用不同的测试数据运行特定测试,请使用 test.only.each
。
test.only.each
有两个 API:
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)
也在别名下: it.skip(name, fn)
、xit(name, fn)
和 xtest(name, fn)
当你维护大型代码库时,有时可能会发现某个测试由于某种原因暂时中断。 如果你想跳过运行此测试,但又不想删除此代码,可以使用 test.skip
指定要跳过的某些测试。
例如,假设你进行了以下测试:
test('it is raining', () => {
expect(inchesOfRain()).toBeGreaterThan(0);
});
test.skip('it is not snowing', () => {
expect(inchesOfSnow()).toBe(0);
});
只有 "正在下雨" 测试将运行,因为其他测试是使用 test.skip
运行的。
你可以注释掉该测试,但使用 test.skip
通常会更好一些,因为它将保持缩进和语法高亮。
test.skip.each(table)(name, fn)
也在别名下: 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)
和 xtest.each`table`(name, fn)
如果你想停止运行数据驱动测试的集合,请使用 test.skip.each
。
test.skip.each
有两个 API:
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)
也在别名下: it.todo(name)
当你计划编写测试时,请使用 test.todo
。 这些测试将在最后的摘要输出中高亮,以便你知道还需要执行多少测试。
const add = (a, b) => a + b;
test.todo('add should be associative');
如果你向 test.todo
传递测试回调函数,它会抛出错误。 如果你已经实现了测试,但不希望它运行,请改用 test.skip
。
TypeScript 用法
仅当你显式导入 Jest API 时,此页面中的 TypeScript 示例才会按照文档说明的方式工作:
import {expect, jest, test} from '@jest/globals';
有关如何使用 TypeScript 设置 Jest 的详细信息,请参阅 入门 指南。
.each
.each
修饰符提供了几种不同的方法来定义测试用例表。 某些 API 具有与传递给 describe
或 test
回调函数的参数类型推断相关的警告。 让我们逐一看一下。
为简单起见,选择 test.each
作为示例,但在可以使用 .each
修饰符的所有情况下,类型推断都是相同的: describe.each
、test.concurrent.only.each
、test.skip.each
等
对象数组
对象数组 API 最冗长,但它使类型推断成为一项轻松的任务。 可以内联 table
:
import {test} from '@jest/globals';
test.each([
{name: 'a', path: 'path/to/a', count: 1, write: true},
{name: 'b', path: 'path/to/b', count: 3},
])('inline table', ({name, path, count, write}) => {
// arguments are typed as expected, e.g. `write: boolean | undefined`
});
或者单独声明为变量:
import {test} from '@jest/globals';
const table = [
{a: 1, b: 2, expected: 'three', extra: true},
{a: 3, b: 4, expected: 'seven', extra: false},
{a: 5, b: 6, expected: 'eleven'},
];
test.each(table)('table as a variable', ({a, b, expected, extra}) => {
// again everything is typed as expected, e.g. `extra: boolean | undefined`
});
数组的数组
数组的数组样式可以与内联表顺利配合:
import {test} from '@jest/globals';
test.each([
[1, 2, 'three', true],
[3, 4, 'seven', false],
[5, 6, 'eleven'],
])('inline table example', (a, b, expected, extra) => {
// arguments are typed as expected, e.g. `extra: boolean | undefined`
});
但是,如果将表声明为单独的变量,则必须将其类型化为元组数组以进行正确的类型推断(仅当行中的所有元素都具有相同类型时才不需要这样做):
import {test} from '@jest/globals';
const table: Array<[number, number, string, boolean?]> = [
[1, 2, 'three', true],
[3, 4, 'seven', false],
[5, 6, 'eleven'],
];
test.each(table)('table as a variable example', (a, b, expected, extra) => {
// without the annotation types are incorrect, e.g. `a: number | string | boolean`
});
模板字面量
如果所有值都具有相同类型,则模板字面量 API 将正确键入参数:
import {test} from '@jest/globals';
test.each`
a | b | expected
${1} | ${2} | ${3}
${3} | ${4} | ${7}
${5} | ${6} | ${11}
`('template literal example', ({a, b, expected}) => {
// all arguments are of type `number`
});
否则它将需要一个泛型类型参数:
import {test} from '@jest/globals';
test.each<{a: number; b: number; expected: string; extra?: boolean}>`
a | b | expected | extra
${1} | ${2} | ${'three'} | ${true}
${3} | ${4} | ${'seven'} | ${false}
${5} | ${6} | ${'eleven'}
`('template literal example', ({a, b, expected, extra}) => {
// without the generic argument in this case types would default to `unknown`
});