跳至主内容
版本:30.0

全局 API

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

在测试文件中,Jest 会将以下方法和对象注入全局环境。您无需通过 require 或 import 即可使用它们。但如果需要显式导入,可通过 import {describe, expect, test} from '@jest/globals' 实现。

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

信息

本页中的 TypeScript 示例仅在显式导入 Jest API 的情况下才能按文档所述正常工作:

import {expect, jest, test} from '@jest/globals';

有关如何设置 Jest 与 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

afterAlldescribe 块内,则会在该描述块末尾执行。

若需在每项测试后而非所有测试后清理,请改用 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

afterEachdescribe 块内,则仅在该描述块内的测试完成后执行。

若需在所有测试完成后仅执行一次清理,请改用 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 解析,因此也支持异步设置。

beforeAlldescribe 块内,则会在该描述块起始处执行。

若需在每项测试前而非所有测试前执行操作,请改用 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 代码块中,它会在该 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.eachdescribe.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 注入测试用例对象的属性生成唯一标题:
      • 嵌套对象值可通过 $variable.path.to.value 注入(仅支持自有属性,例如 $variable.constructor.name 无效)
      • 使用 $# 注入测试用例索引
      • $variable 不能与 printf 格式化混用(%% 除外)
  • 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 从标记模板表达式中注入测试数据到套件标题,并使用 $# 表示行索引。

    • 要注入嵌套对象值,可以提供键路径,例如 $variable.path.to.value(仅适用于“自有”属性,例如 $variable.constructor.name 将不起作用)
  • fnFunction 类型,表示要运行的测试套件函数,该函数将接收测试数据对象。

  • 可选地,你可以提供 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 代码块时,可使用 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 支持两种调用方式:

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 代码块本身仍会执行。如需跳过相关设置逻辑,请在 beforeAllbeforeEach 块中处理。

describe.skip.each(table)(name, fn)

别名:xdescribe.each(table)(name, fn)xdescribe.each`table`(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(毫秒单位)用于设置超时时间,默认 5 秒。

test 返回 Promise 对象,Jest 会等待其状态变更后才完成测试。例如 fetchBeverageList() 返回应包含 lemon 的列表时:

test('has lemon in it', () => {
return fetchBeverageList().then(list => {
expect(list).toContain('lemon');
});
});

即使 test 调用立即返回,测试需等待 promise 解析后才算完成。详见异步测试指南

技巧

当测试函数接收参数(通常命名为 done)时,Jest 也会等待其回调。这在测试回调函数时特别有用。

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.eachtest.each 允许编写一次测试并传入多组数据,所有测试将异步并发执行。

test.concurrent.each 支持两种调用方式:

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 将模板表达式数据注入标题

    • 嵌套对象使用键路径如 $variable.path.to.value(仅支持自有属性,例如 $variable.constructor.name 就不会生效)
  • 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 支持两种调用方式:

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 支持两种调用方式:

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.eachtest.each 允许编写一次测试并传入多组数据。

test.each 支持两种调用方式:

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 注入测试用例对象的属性:
      • 嵌套对象使用键路径如 $variable.path.to.value(仅支持"own" properties,例如 $variable.constructor.name 不可用)
      • $# 可注入测试用例索引
      • %% 外,$variable 不可与 printf 格式混用
  • 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 将模板表达式数据注入标题

    • 嵌套对象使用键路径如 $variable.path.to.value(仅支持自有属性,例如 $variable.constructor.name 就不会生效)
  • 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 提供两种调用方式:

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);
});

仅 "it is raining" 测试会运行,其他测试因使用 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 提供两种调用方式:

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 用法

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

信息

本页中的 TypeScript 示例仅在显式导入 Jest API 的情况下才能按文档所述正常工作:

import {expect, jest, test} from '@jest/globals';

有关如何设置 Jest 与 TypeScript 配合使用的详细信息,请查阅入门指南

.each 修饰符

.each 修饰符提供多种定义测试用例表格的方式,部分 API 在传递给 describetest 回调函数的参数类型推断方面需特别注意。我们将逐一解析:

备注

示例选用 test.each 保持简洁,但类型推断规则同样适用于其他 .each 修饰场景:describe.eachtest.concurrent.only.eachtest.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 same type', ({a, b, expected}) => {
// all arguments are of type `number` because all inputs (a, b, expected) are of type `number`
});

如果输入值类型不同,参数会被类型化为所有输入类型的联合类型(即模板字面量内部变量的类型):

import {test} from '@jest/globals';

test.each`
a | b | expected
${1} | ${2} | ${'three'}
${3} | ${4} | ${'seven'}
${5} | ${6} | ${'eleven'}
`('template literal example different types', ({a, b, expected}) => {
// all arguments are of type `number | string` because some inputs (a, b) are of type `number` and some others (expected) are of type `string`
});

否则,如果你希望每个参数都有正确的类型,就必须显式提供泛型类型参数:

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}) => {
// all arguments are typed as expected, e.g. `a: number`, `expected: string`, `extra: boolean | undefined`
});
注意

请注意,模板字面量内部的变量不会进行类型检查,因此你必须确保它们的类型正确。

import {test} from '@jest/globals';

test.each<{a: number; expected: string}>`
a | expected
${1} | ${'one'}
${'will not raise TS error'} | ${'two'}
${3} | ${'three'}
`('template literal with wrongly typed input', ({a, expected}) => {
// all arguments are typed as stated in the generic: `a: number`, `expected: string`
// WARNING: `a` is of type `number` but will be a string in the 2nd test case.
});