# 一、Jest 基本概念

# npm 安装:

1. npm install jest -D(安装到本地)
2. npm install jest -g(安装到全局)

# 运行:

  1. npx jest (安装到本地的前提下)

  2. jest (安装到全局的前提下)

  3. 修改 "script" 中的 "test" 为 "jest" 后使用 npm run testnpm t

# 零配置:

但测试用例文件名格式为 **test.js(默认配置下)

# 基本方法:

・分组(Test Group):descripe (描述语,function)

・测试用例(Test Case):test (描述语,function)

・断言(Assert):expect (运行需测试的方法并返回实际结果).toBe (预期结果)

Pencil.query =(name, url)=> { // 方法,返回捕获
    // ?hello=test&wonghan=handsome
    var reg = new RegExp('(?:\?|&)' + name + '=(.*?)(?:&|$)')
    var ret = reg.exec(url) || []
    return ret[1]
}
test('query',()=>{ // testCase
    // 断言
    expect(Pencil.query('hello', '?hello=test')).toBe('test')
    expect(Pencil.query('hello', '?hello2=test')).toBe(undefined)
    // 可以写多个 ecpect ()
})
test('query2',()=>{
    expect(Pencil.query('hello/test', '?hello/test=test')).toBe('test')
})
    // 可以写多个 test ()
describe('test query',()=>{
test('query3',()=>{ // testCase
    // assert
    expect(Pencil.query('hello', '?hello=test')).toBe('test')
    expect(Pencil.query('hello', '?hello2=test')).toBe(undefined)
    })
})

# 二、Jest 配置

虽然说 Jest 是零配置,但也是可以配置

# (一)配置位置

# 1. package.json

package.json 添加配置项 "jest" :

# 2. jest.config.js

新建 jest.config.js 并添加配置项 module.exports = { 配置项 }

# 3. 命令行(独有的 option)

见:命令行配置

# (二)配置项

# 1. testMatch

设置识别哪些文件是测试文件(glob 形式),与 testRegex 互斥,不能同时写

testMatch: ['**/__tests__/**/*.js?(x)','**/?(*.)(spec|test).js?(x)']

# 2. testRegex

设置识别哪些文件是测试文件(正则形式),与 testMatch 互斥,不能同时写

testRegex: '(/__tests__).*|(\\.|/)(test|spec))\\.jsx?$'

# 3. testRnviroment

测试环境,默认值是:jsdom,可修改为 node

testEnvironment: 'jsdom'

# 4. rootDir

默认值:当前目录,一般是 package.json 所在的目录。

rootDir: ' '

# 5. moduleFileExtensions

测试文件的类型

moduleFileExtensions: ['js','json','jsx','node']

# 一般配置:

module.exports = {undefined
  testMatch: ['<rootDir>/test/**/*.js'],
  testEnvironment: 'jsdom',
  rootDir: '',
  moduleFileExtensions: ['js','json','jsx','node']
}

# 三、Jest Matchers

Matchers 俗称断言库,例如上面的 expect ().toBe () 便是其中之一,其他常见用法如下:

# 1. 相等断言

  • toBe(value)****: 比较数字、string
  • toEqual(value)****: 比较 Object、array
  • toBeNull()
  • toBeUndefined()

# 2. 包含断言

  • toHaveProperty(keyPath, value)****: 是否有对应的属性
  • toContain(item)****: 是否包含对应的值,括号里写上 array、string
  • toMatch(regexpOrString)****: 括号里写上正则

# 3. 逻辑断言

  • toBeTruthy()
  • toBeFalsy()

在 JavaScript 中,有六个 falsy 值:false,0,'',null, undefined,和 NaN。其他一切都是 Truthy。

  • toBeGreaterThan(number)****: 大于
  • toBeLessThan(number)****: 小于

# 4.not

取反,用法见下面例子

test('matchers',()=>{
    const a = {
        hello: 'jest',
        hi :{
            name: 'jest'
    }
}
const b = {
    hello: 'jest',
    hi: {
        name: 'jest'
    }
}
// 以下结果均为 true
expect(a).toEqual(b)
expect([1,2,3]).toEqual([1,2,3])
expect(null).toBeNull()
expect([1,2,3]).toContain(1)
expect(b).toHaveProperty('hi')
expect('123').toContain('2')
expect('123').toMatch(/^\d+$/)
expect('123').not.toContain('4')
})

・使用 npx jest 测试执行,结果为 passed

从软件开发的角度来说项目技术的复杂度会带来开发,测试,交付流程等的复杂度的成倍提升,而我们知道测试是整个软件交付流程中非常重要的一个环节,在重前端的形势下,前端的测试的构建也显示尤为重要。

运行测试时,Jest 会自动模拟依赖。Jest 自动为每个依赖的模块生成 Mock,并默认提供这些 Mock,这样就可以很容易地隔离模块的依赖。集成了断言库,不需要再引入第三方的断言库,并且非常完美的支持 React 组件化测试

新建文件夹然后通过 npm 命令安装:

npm install --save-dev jest

让我们来测试一个简单两个数字相加的 function 吧,新建 Sum.js

function sum(a, b){undefined
  return a + b;
}
module.exports = sum;

然后新一个 Sum.test.js 的文件来测试我们的 sum function:

const sum = require('./Sum.js')
test('test 1 plus 2 result', () => {undefined
 expect(sum(1 , 2)).toBe(3);
})
test('test 2 plus 2 should equal 4', () => {undefined
 expect(sum(2 , 2)).toBe(4);
})

需要在 package.json 中加入下面配置:

{undefined
 "scripts": {undefined
  "test": "jest"
 }
}

Jest 支持 Babel,我们将很轻松的使用 ES6 的高级语法

Jest 支持 webpack,非常方便的使用它来管理我们的项目

Jest 支持 TypeScript

// be and equal
  expect(4 * 2).toBe(8);                      // ===
  expect({bar: 'bar'}).toEqual({bar: 'baz'}); // deep equal
  expect(1).not.toBe(2);
  // boolean
  expect(1 === 2).toBeFalsy();
  expect(false).not.toBeTruthy();
  // comapre
  expect(8).toBeGreaterThan(7);
  expect(7).toBeGreaterThanOrEqual(7);
  expect(6).toBeLessThan(7);
  expect(6).toBeLessThanOrEqual(6);
  // Promise
  expect(Promise.resolve('problem')).resolves.toBe('problem');
  expect(Promise.reject('assign')).rejects.toBe('assign');
  // contain
  expect(['apple', 'banana']).toContain('banana');
  expect([{name: 'Homer'}]).toContainEqual({name: 'Homer'});
  
  // match
  expect('NBA').toMatch(/^NB/);
  expect({name: 'Homer', age: 45}).toMatchObject({name: 'Homer'});

# API 列表

# automock

[boolean] 默认值︰ false

  • 这个选项告诉 Jest 所有的导入模块都自动 mock 下。

示例:

// utils.js
export default {
  authorize: () => {
    return 'token';
  },
  isAuthorized: secret => secret === 'wizard',
};
//__tests__/automocking.test.js
import utils from '../utils';
test('if utils mocked automatically', () => {
  // Public methods of `utils` are now mock functions
  expect(utils.authorize.mock).toBeTruthy();
  expect(utils.isAuthorized.mock).toBeTruthy();
  // You can provide them with your own implementation
  // or pass the expected return value
  utils.authorize.mockReturnValue('mocked_token');
  utils.isAuthorized.mockReturnValue(true);
  expect(utils.authorize()).toBe('mocked_token');
  expect(utils.isAuthorized('not_wizard')).toBeTruthy();
});

注意:node modules 当源以下 mocks 时会自动执行 mock。核心模块,例如 fs ,是不会默认 mock 的,需要手动设置目录下: jest.mock('fs')

# bail [number| boolean]

默认: 0

  • Jest 默认将所有测试产生的信息都通过控制台显示,保释选项可以让你配置开玩笑在每次失败后将停止运行测试,设置与设置 1 一样是真实的。

# browser [boolean]

默认值︰ false

  • 当解析模块的时候,是否 package.json 在中的 Browserify 的浏览器中。 "browser"

# cacheDirectory [string]

默认值︰ "/tmp/<path>"

  • Jest 用来存储使用依赖信息缓存的目录。
  • Jest 尝试去扫描你的依赖树一次(搁置)并且依赖树缓存起来,其 Object 是在运行测试时需要进行文件的示例。这个配置让你可以自定义将缓存数据储存在磁盘的那个位置。

# clearMocks [boolean]

默认值︰ false

  • 在每个测试前自动调用的实例和实例调用。在每个测试之前 jest.clearAllMocks ,但不会删除已经有的实例调用。

# collectCoverage [boolean]

默认值︰ false

  • 复查所有文件,可能会让你的测试执行速度明显减半。

# collectCoverageFrom [array]

默认值: undefined

  • 参数是 glob 模式的列表,有哪些集合的文件是需要收集的。如果文件匹配了,那么被收集作为覆盖的基数,这个文件没有测试的用例。

示例:

{
  "collectCoverageFrom": [
    "**/*.{js,jsx}",
    "!**/node_modules/**",
    "!**/vendor/**"
  ]
}

上面的例子中搜索在 rootDir 下面所有的以 js 出的文件或 jsx 为后缀的目录,同时派 node_modules
和 vendor 下的文件。

注意:该选项要求被设置 collectCoverage 成真实,或者通过 --coverage 参数来调用 Jest。

# coverageDirectory [string]

默认值: undefined

  • 开玩笑输出覆盖信息文件的目录。

# coveragePathIgnorePatterns [array<string>]

默认值︰ ["node_modules"]

  • 比如提出覆盖的文件列表,模式 string 默认匹配全路径,可以添加 <rootDir> token 来放置某个系统环境里面把你的覆盖文件遗漏了 ["<rootDir>/build/", "<rootDir>/node_modules/"]

# coverageProvider [string]

  • 使用哪个供应商来指导到底代码的覆盖测试,允许的参数有 babel (默认) —— 用于 v8

  • 注意: v8 还比较像,比较的配置可能会有一些瑕疵。

# coverageReporters [array<string>]

默认: ["json", "lcov", "text", "clover"]

  • 包含了 reporters 名字的列表,而 Jest 会用他们来覆盖报告。至于 reporters 有哪些,请参考:伊斯坦 booleanreporters

# coverageThreshold [Object]

默认值: undefined

  • 如果没有达到目标值,正确 global 值是作为一个覆盖结构的最小目标值来设置的。最小的值,如果给了一个负数就表示最大的支持的允许值。

举个例子,下面的配置我们的分支数和覆盖率小 8%,和 10% 的举起未覆盖率声明

{
  ...
  "jest": {
    "coverageThreshold": {
      "global": {
        "branches": 80,
        "functions": 80,
        "lines": 80,
        "statements": -10
      }
    }
  }
}

# dependencyExtractor [string]

默认值: undefined

  • 这个选项允许特定依赖提取器的使用,必须满足是一个节点模块,同时导出的 Object 中包含 extract 函数。

例如:

const fs = require('fs');
const crypto = require('crypto');
module.exports = {
  extract(code, filePath, defaultExtract) {
    const deps = defaultExtract(code, filePath);
    // Scan the file and add dependencies in `deps` (which is a `Set`)
    return deps;
  },
  getCacheKey() {
    return crypto
      .createHash('md5')
      .update(fs.readFileSync(__filename))
      .digest('hex');
  },
};

extract 函数应该返回一个代码里面的依赖项,并且返回的结果是可以遍历的。(例如 Array , Set , etc.) 。

模块空间包含一个 getCacheKey 函数来生成一个缓存的 key,用于决定逻辑是否变更。

# displayName [string,Object]

默认值: undefined

  • 允许在测试的时候打印显示标签。这在有多个 repo 和多个 jest 配置文件的时候很好用。
module.exports = {
  displayName: 'CLIENT',
};

或者

module.exports = {
  displayName: {
    name: 'CLIENT',
    color: 'blue',
  },
};

# errorOnDeprecated [boolean]

默认值︰ false

  • 例外的 API 抛出提示性的错误信息。

# extraGlobals [array<string>]

默认值: undefined

  • 测试文件在 vm Math 中运行,这会减慢对全局上下文属性(例如)的调用。使用此选项,您可以指定要在 vm 内定义的额外属性,以便更快地查找。

  • 例如,如果您的测试 Math 经常调用,您可以通过设置 extraGlobals .

{
  ...
  "jest": {
    "extraGlobals": ["Math"]
  }
}

# forceCoverageMatch [array<string>]

默认: ['']

  • 收集代码覆盖率通常会忽略测试文件。使用此选项,您可以覆盖此行为并在代码覆盖中包含其他被忽略的文件。

  • 例如,如果您在以 .t.js 如下扩展名命名的源文件中有测试:

// sum.t.js
export function sum(a, b) {
  return a + b;
}
if (process.env.NODE_ENV === 'test') {
  test('sum', () => {
    expect(sum(1, 2)).toBe(3);
  });
}

你可以通过设置 forceCoverageMatch 从这些文件中收集覆盖率。

{
  ...
  "jest": {
    "forceCoverageMatch": ["**/*.t.js"]
  }
}

# globals [Object]

默认值: {}

  • 各种类似的变量,在所有测试环境下都可以访问。

下面,创建代码变量的环境有一个所有 true 的测试变量 __DEV__

{
  ...
  "jest": {
    "globals": {
      "__DEV__": true
    }
  }
}

注意,如果你在这指定了一个类似的值(例如,Object 或物品),在之后的测试中,这个代码不会改变被引用的值,这对于其他测试来说是有效的。此外, globals Object 必须是 json-serializable,因此不能用于指定全局函数。要实现这种功能,应该使用 setupFiles

# globalSetup [string]

默认值: undefined

  • 此选项允许使用自定义全局设置模块,该模块导出在所有测试套件之前触发一次的异步函数。此函数获取 Jest 的 globalConfig Object 作为参数。

  • 注意:项目中配置的全局设置模块(使用多项目运行器)仅当您从该项目运行至少一个测试时才会触发。

  • 注意:通过 定义的任何全局变量 globalSetup 只能在 globalTeardown . 您无法检索在测试套件中定义的全局变量。

  • 注意:当代码转换应用于链接的设置文件时,Jest 不会转换 node_modules . 这是由于需要加载实际的转换器(例如 babeltypescript )来执行转换。

示例:

// setup.js
module.exports = async () => {
  // ...
  // Set reference to mongod in order to close the server during teardown.
  global.__MONGOD__ = mongod;
};
// teardown.js
module.exports = async function() {
  await global.__MONGOD__.stop();
};

# globalTeardown [string]

默认值: undefined

  • 此选项允许使用自定义全局拆卸模块,该模块导出在所有测试套件之后触发一次的异步函数。此函数获取 Jest 的 globalConfig Object 作为参数。

  • 注意:在项目中配置的全局拆卸模块(使用多项目运行器)仅在您从该项目运行至少一个测试时才会触发。

  • 注意:关于 node_modules as for 转换的相同警告 globalSetup 适用于 globalTeardown .

# maxConcurrency [number]

默认: 5

  • 限制使用时允许同时运行的测试数量的数字 test.concurrent 。一旦插槽被释放,任何超过此限制的测试都将排队并执行。

# moduleDirectories [array<string>]

默认值︰ ["node_modules"]

  • 要从所需模块的位置向上递归搜索的目录名称 array。设置此选项将覆盖默认值,如果您仍希望搜索 node_modules 包,请将其与任何其他选项一起包含: ["node_modules", "bower_components"]

# moduleFileExtensions [array<string>]

默认: ["js", "json", "jsx", "ts", "tsx", "node"]

  • 您的模块使用的一系列文件扩展名。如果您需要模块而不指定文件扩展名,这些是 Jest 将按照从左到右的顺序查找的扩展名。

  • 我们建议将项目中最常用的扩展放在左侧,因此如果您使用 TypeScript,您可能需要考虑将 “ts” 和 / 或 “tsx” 移动到 array 的开头。

# moduleNameMapper [Object<string,string>]

默认值︰ null

  • 从正则表达式到 moduleName 的映射,允许存根资源,例如带有单个模块的图像或样式。

  • 默认情况下,映射到别名的模块不会被模拟,无论是否启用自动模拟。

  • 如果要使用文件路径,请使用 <rootDir> string 标记来引用值。 rootDir

  • 此外,您可以使用编号的反向引用替换捕获的正则表达式组。

示例:

{
  "moduleNameMapper": {
    "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
    "^[./a-zA-Z0-9$_-]+\\.png$": "<rootDir>/RelativeImageStub.js",
    "module_name_(.*)": "<rootDir>/substituted_module_$1.js"
  }
}

定义映射的顺序很重要。图案被一一检查,直到适合。最具体的规则应首先列出。

注意:如果您提供没有边界的 moduleName ^$ ,可能会导致难以发现错误。例如 relay ,将替换 relay 名称中包含子 string 的所有模块: relayreact-relay 并且 graphql-relay 都将指向您的存根。

# modulePathIgnorePatterns [array<string>]

默认值: []

  • 在将这些路径视为对模块加载器 “可见” 之前,与所有模块路径匹配的正则表达式模式 string array。如果给定模块的路径与任何模式匹配,它将无法 require() 在测试环境中使用。

  • 这些模式 string 与完整路径匹配。使用 <rootDir> string 标记来包含项目根目录的路径,以防止它意外忽略可能具有不同根目录的不同环境中的所有文件。示例: ["<rootDir>/build/"]

# modulePaths [array<string>]

默认值: []

  • 设置 NODE_PATH env 变量的另一种 API modulePaths 是解析模块时要搜索的其他位置的绝对路径 array。使用 <rootDir> string 标记包含项目根目录的路径。示例: ["<rootDir>/app/"]

# notify [boolean]

默认值︰ false

  • 激活测试结果通知。

# notifyMode [string]

默认: failure-change

  • 指定通知模式。需要 notify: true .

# Modes

  • always : 总是发送通知。
  • failure :当测试失败时发送通知。
  • success :测试通过时发送通知。
  • change : 当状态改变时发送通知。
  • success-change :当测试通过或失败时发送通知。
  • failure-change :当测试失败或通过时发送通知。

# preset [string]

默认值: undefined

  • 用作 Jest 配置基础的预设。预设应该指向在根目录下具有 jest-preset.json or 文件的 npm 模块。 jest-preset.js

  • 例如,此预设 foo-bar/jest-preset.js 将配置如下:

{
  "preset": "foo-bar"
}

预设也可以是相对文件系统路径。

{
  "preset": "./node_modules/foo-bar/jest-preset.js"
}

# prettierPath [string]

默认: 'prettier'

  • prettier 设置用于更新内联快照的节点模块的路径。

# projects [array<string | ProjectConfig>]

默认值: undefined

  • projects 配置提供了一组路径或 glob 模式时,Jest 将同时在所有指定项目中运行测试。这对于 monorepos 或同时处理多个项目非常有用。
{
  "projects": ["<rootDir>", "<rootDir>/examples/*"]
}

此示例配置将在根目录以及示例目录中的每个文件夹中运行 Jest。您可以在同一个 Jest 实例中运行无限数量的项目。

项目功能也可用于运行多个配置或多个运行。为此,您可以传递一组配置 Object。例如,在 Jest 的同一次调用中同时运行测试和 ESLint(通过 jest-runner-eslint ):

{
  "projects": [
    {
      "displayName": "test"
    },
    {
      "displayName": "lint",
      "runner": "jest-runner-eslint",
      "testMatch": ["<rootDir>/**/*.js"]
    }
  ]
}

注意:使用多项目运行器时,建议 displayName 为每个项目添加一个。这将在 displayName 其测试旁边显示项 Object。

# reporters [array<moduleName | [moduleName ,options]>]

默认值: undefined

  • 使用此配置选项将自定义报告器添加到 Jest。自定义报告器是一个实现 onRunStart , onTestStart , onTestResult , onRunComplete 方法的类,当任何这些事件发生时将调用这些方法。

  • 如果指定了自定义报告器,则默认的 Jest 报告器将被覆盖。要保留默认报告器, default 可以作为 moduleName 传递。

这将覆盖默认 reporters:

{
  "reporters": ["<rootDir>/my-custom-reporter.js"]
}

除了 Jest 提供的默认报告器之外,这将使用自定义报告器:

{
  "reporters": ["default", "<rootDir>/my-custom-reporter.js"]
}

此外,可以通过将 options Object 作为第二个参数传递来配置自定义报告器:

{
  "reporters": [
    "default",
    ["<rootDir>/my-custom-reporter.js", {"banana": "yes", "pineapple": "no"}]
  ]
}

自定义报告器模块必须定义一个将 a GlobalConfig 和报告器选项作为构造函数参数的类:

示例 reporters:

// my-custom-reporter.js
class MyCustomReporter {
  constructor(globalConfig, options) {
    this._globalConfig = globalConfig;
    this._options = options;
  }
  onRunComplete(contexts, results) {
    console.log('Custom reporter output:');
    console.log('GlobalConfig: ', this._globalConfig);
    console.log('Options: ', this._options);
  }
}
module.exports = MyCustomReporter;
// or export default MyCustomReporter;

getLastError() 自定义报告器还可以通过从方法返回错误来强制 Jest 以非 0 代码退出

class MyCustomReporter {
  // ...
  getLastError() {
    if (this._shouldFail) {
      return new Error('my-custom-reporter.js reported an error');
    }
  }
}

有关方法和参数类型的完整列表,请参见 packages/jest-reporters/src/types.ts Reporter 中的接口

# resetMocks [boolean]

默认值︰ false

  • 每次测试前自动重置模拟状态。相当于 jest.resetAllMocks() 每次测试前调用。这将导致任何模拟删除其虚假实现但不会恢复其初始实现。

# resetModules [boolean]

默认值︰ false

  • 默认情况下,每个测试文件都有自己独立的模块注册表。启用 resetModules 更进一步,并在运行每个单独的测试之前重置模块注册表。这对于隔离每个测试的模块很有用,这样本地模块状态就不会在测试之间发生冲突。这可以使用 jest.resetModules() .

# resolver [string]

默认值: undefined

  • 此选项允许使用自定义解析器。这个解析器必须是一个节点模块,它导出一个函数,该函数需要一个 string 作为解析路径的第一个参数,以及一个具有以下结构的 Object 作为第二个参数:
{
  "basedir": string,
  "browser": bool,
  "defaultResolver": "function(request, options)",
  "extensions": [string],
  "moduleDirectory": [string],
  "paths": [string],
  "rootDir": [string]
}

该函数应该返回应该解析的模块的路径,或者如果找不到模块则抛出错误。

注意:作为选项传递的 defaultResolver 是 Jest 默认解析器,在您编写自定义解析器时可能很有用。它采用与您的自定义参数相同的参数,例如(请求、选项)。

# restoreMocks [boolean]

默认值︰ false

  • 每次测试前自动恢复模拟状态。相当于 jest.restoreAllMocks() 每次测试前调用。这将导致任何模拟删除其虚假实现并恢复其初始实现。

# rootDir [string]

默认值:包含您的 Jest 配置文件 的目录的根目录,或者 package.json 如果 pwd 没有 package.json 找到

  • Jest 应该扫描其中的测试和模块的根目录。如果您将 Jest 配置放在您的内部 package.json 并希望根目录成为您的 repo 的根目录,则此配置参数的值将默认为 package.json .

  • 通常,您需要将其设置为 'src''lib' ,对应于存储库中代码的存储位置。

  • 请注意, '<rootDir>' 在任何其他基于路径的配置设置中用作 string 标记将引用此值。因此,例如,如果您希望 setupFiles 配置条目指向 env-setup.js 项目根目录下的文件,则可以将其值设置为 ["<rootDir>/env-setup.js"] .

# roots [array<string>]

默认值︰ ["<rootDir>"]

  • Jest 应该用来在其中搜索文件的目录的路径列表。

  • 有时您只希望 Jest 在单个子目录中搜索(例如 src/ 在您的仓库中有一个目录的情况),但阻止它访问其余的仓库。

  • 注意:虽然 rootDir 主要用作在其他配置选项中重复使用的令牌, roots 但 Jest 的内部使用它来定位测试文件和源文件node_modules 这也适用于从 ( __mocks__ 将需要生活在其中之一) 中搜索模块的手动模拟时 roots

  • 注意:默认情况下, roots 只有一个条目 <rootDir> ,但在某些情况下,您可能希望在一个项目中有多个根,例如 roots: ["<rootDir>/src/", "<rootDir>/tests/"] .

# runner [string]

默认: "jest-runner"

此选项允许您使用自定义运行程序而不是 Jest 的默认测试运行程序。跑步者的例子包括:

注意: runner 属性值可以省略 jest-runner- 包名的前缀。

要编写测试运行器,请导出一个在构造函数中接受的类 globalConfig ,并具有一个 runTests 带有签名的方法:

async runTests(
  tests: Array<Test>,
  watcher: TestWatcher,
  onStart: OnTestStart,
  onResult: OnTestSuccess,
  onFailure: OnTestFailure,
  options: TestRunnerOptions,
): Promise<void>

如果您需要将测试运行程序限制为仅以串行方式运行而不是并行执行,则您的类应将属性 isSerial 设置为 true .

# setupFiles [array]

默认值: []

  • 运行一些代码以配置或设置测试环境的模块的路径列表。每个 setupFile 将在每个测试文件中运行一次。由于每个测试都在其自己的环境中运行,因此这些脚本将在执行测试代码本身之前立即在测试环境中执行。

  • 还值得注意的是, setupFiles 将在之前 setupFilesAfterEnv 执行。

# setupFilesAfterEnv [array]

默认值: []

  • 运行一些代码以在每次测试之前配置或设置测试框架的模块的路径列表。由于 setupFiles 在环境中安装测试框架之前执行,因此该脚本文件为您提供了在环境中安装测试框架后立即运行一些代码的机会。

  • 如果您希望路径相对于项 Object 根目录,请包含 <rootDir> 在路径的 string 中,例如 "<rootDir>/a-configs-folder" .

  • jasmine 例如,Jest 通过猴子修补 jasmine API 提供了几个插件来完成这项工作。如果你想添加更多的 jasmine 插件(或者如果你想要一些自定义的、项目范围的匹配器),你可以在这些模块中这样做。

  • 注意: setupTestFrameworkScriptFile 不赞成使用 setupFilesAfterEnv .

setupFilesAfterEnv jest.config.js 中的示例 array:

module.exports = {
  setupFilesAfterEnv: ['./jest.setup.js'],
};

示例 jest.setup.js 文件

jest.setTimeout(10000); // in milliseconds

# snapshotResolver [string]

默认值: undefined

  • 可以解析测试 <-> 快照路径的模块的路径。此配置选项允许您自定义 Jest 在磁盘上存储快照文件的位置。

  • 示例快照解析器模块:

module.exports = {
  // resolves from test to snapshot path
  resolveSnapshotPath: (testPath, snapshotExtension) =>
    testPath.replace('__tests__', '__snapshots__') + snapshotExtension,
  // resolves from snapshot to test path
  resolveTestPath: (snapshotFilePath, snapshotExtension) =>
    snapshotFilePath
      .replace('__snapshots__', '__tests__')
      .slice(0, -snapshotExtension.length),
  // Example test path, used for preflight consistency check of the implementation above
  testPathForConsistencyCheck: 'some/__tests__/example.test.js',
};

# snapshotSerializers [array<string>]

默认值: []

  • Jest 应用于快照测试的快照序列化程序模块的路径列表。

  • Jest 具有内置 JavaScript 类型、HTML 元素 (Jest 20.0.0+)、ImmutableJS (Jest 20.0.0+) 和 React 元素的默认序列化程序。有关更多信息,请参阅快照测试教程

示例序列化模块:

// my-serializer-module
module.exports = {
  print(val, serialize, indent) {
    return 'Pretty foo: ' + serialize(val.foo);
  },
  test(val) {
    return val && val.hasOwnProperty('foo');
  },
};

serialize 是一个使用现有插件序列化值的函数。

my-serializer-module 用作序列化程序,配置如下:

{
  ...
  "jest": {
    "snapshotSerializers": ["my-serializer-module"]
  }
}

最后测试如下:

test(() => {
  const bar = {
    foo: {
      x: 1,
      y: 2,
    },
  };
  expect(bar).toMatchSnapshot();
});

渲染快照:

Pretty foo: Object {
  "x": 1,
  "y": 2,
}

要使依赖项显式而不是隐式,您可以调用 expect.addSnapshotSerializer 为单个测试文件添加模块,而不是 snapshotSerializers 在 Jest 配置中添加其路径。

# testEnvironment [string]

默认值︰ "jsdom"

  • 将用于测试的测试环境。Jest 中的默认环境是通过 jsdom 实现的类似浏览器的环境。如果您正在构建节点服务,则可以使用该 node 选项来使用类似节点的环境。

  • 通过在文件顶部添加一个 @jest-environment docblock,您可以指定另一个环境用于该文件中的所有测试:

/**
 * @jest-environment jsdom
 */
test('use jsdom in this test file', () => {
  const element = document.createElement('div');
  expect(element).not.toBeNull();
});

您可以创建自己的模块,用于设置测试环境。模块必须导出一个带有 setup , teardownrunScript 方法的类。您还可以通过将变量分配给 this.global Object 来将此模块中的变量传递给您的测试套件 —— 这将使它们在您的测试套件中作为全局变量可用。

该类可以选择公开一个 handleTestEvent 方法来绑定到由 jest-circus .

测试文件中的任何 docblock pragma 都将传递给环境构造函数,并可用于每个测试的配置。如果 pragma 没有值,它将出现在 Object 中,其值设置为空 string。如果 pragma 不存在,则它不会出现在 Object 中。

注意:TestEnvironment 是沙盒的。每个测试套件都将在他们自己的 TestEnvironment 中触发 setup/teardown。

示例:

// my-custom-environment
const NodeEnvironment = require('jest-environment-node');
class CustomEnvironment extends NodeEnvironment {
  constructor(config, context) {
    super(config, context);
    this.testPath = context.testPath;
    this.docblockPragmas = context.docblockPragmas;
  }
  async setup() {
    await super.setup();
    await someSetupTasks(this.testPath);
    this.global.someGlobalObject = createGlobalObject();
    // Will trigger if docblock contains @my-custom-pragma my-pragma-value
    if (this.docblockPragmas['my-custom-pragma'] === 'my-pragma-value') {
      // ...
    }
  }
  async teardown() {
    this.global.someGlobalObject = destroyGlobalObject();
    await someTeardownTasks();
    await super.teardown();
  }
  runScript(script) {
    return super.runScript(script);
  }
  handleTestEvent(event, state) {
    if (event.name === 'test_start') {
      // ...
    }
  }
}
module.exports = CustomEnvironment;
// my-test-suite
let someGlobalObject;
beforeAll(() => {
  someGlobalObject = global.someGlobalObject;
});

# testEnvironmentOptions [Object]

默认值: {}

  • 将传递给 testEnvironment . 相关选项取决于环境。例如,您可以覆盖提供给 jsdom 的选项,例如 {userAgent: "Agent/007"} .

# testMatch [array<string>]

(默认 [ "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ] :)

  • Jest 用于检测测试文件的 glob 模式。默认情况下,它会查找文件夹内的 、 和 文件 .js ,以及 .jsx 任何带有 or 后缀的文件(例如 or )。它还将查找名为 or 的文件。 .ts``.tsx``__tests__``.test``.spec``Component.test.js``Component.spec.js``test.js``spec.js

  • 有关您可以指定的模式的详细信息,请参阅 micromatch 包。

  • 另请参阅 [ testRegex string | array],但请注意,您不能同时指定这两个选项。

# testPathIgnorePatterns [array<string>]

默认值︰ ["node_modules"]

  • 在执行测试之前与所有测试路径匹配的正则表达式模式 string array。如果测试路径匹配任何模式,它将被跳过。

  • 这些模式 string 与完整路径匹配。使用 <rootDir> string 标记来包含项目根目录的路径,以防止它意外忽略可能具有不同根目录的不同环境中的所有文件。示例: ["<rootDir>/build/", "<rootDir>/node_modules/"]

# testRegex [string | array<string>]

默认: (/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$

  • Jest 用于检测测试文件的模式。默认情况下,它会查找文件夹内的 、 和 文件 .js ,以及 .jsx 任何带有 or 后缀的文件(例如 or )。它还将查找名为 or 的文件。另请参阅 [array],但请注意,您不能同时指定这两个选项。 .ts``.tsx``__tests__``.test``.spec``Component.test.js``Component.spec.js``test.js``spec.js testMatch

以下是默认正则表达式的可视化:

├── __tests__
│   └── component.spec.js # test
│   └── anything # test
├── package.json # not test
├── foo.test.js # test
├── bar.spec.jsx # test
└── component.js # not test

注意: testRegex 将尝试使用绝对文件路径检测测试文件,因此具有名称匹配的文件夹会将所有文件作为测试运行

# testResultsProcessor [string]

默认值: undefined

  • 此选项允许使用自定义结果处理器。该处理器必须是一个节点模块,它导出一个函数,该函数期望具有以下结构的 Object 作为第一个参数并返回它:
{
  "success": bool,
  "startTime": epoch,
  "numTotalTestSuites": number,
  "numPassedTestSuites": number,
  "numFailedTestSuites": number,
  "numRuntimeErrorTestSuites": number,
  "numTotalTests": number,
  "numPassedTests": number,
  "numFailedTests": number,
  "numPendingTests": number,
  "numTodoTests": number,
  "openHandles": Array<Error>,
  "testResults": [{
    "numFailingTests": number,
    "numPassingTests": number,
    "numPendingTests": number,
    "testResults": [{
      "title": string (message in it block),
      "status": "failed" | "pending" | "passed",
      "ancestorTitles": [string (message in describe blocks)],
      "failureMessages": [string],
      "numPassingAsserts": number,
      "location": {
        "column": number,
        "line": number
      }
    },
    ...
    ],
    "perfStats": {
      "start": epoch,
      "end": epoch
    },
    "testFilePath": absolute path to test file,
    "coverage": {}
  },
  ...
  ]
}

# testRunner [string]

默认值︰ jasmine2

  • 此选项允许使用自定义测试运行器。默认值为 jasmine2。可以通过指定测试运行程序实现的路径来提供自定义测试运行程序。

  • 测试运行器模块必须导出具有以下签名的函数:

function testRunner(
  config: Config,
  environment: Environment,
  runtime: Runtime,
  testPath: string,
): Promise<TestResult>;

可以在我们的默认 jasmine2 测试运行程序包中找到此类功能的示例。

# testSequencer [string]

默认: @jest/test-sequencer

  • 此选项允许您使用自定义音序器而不是 Jest 的默认值。 sort 可以选择返回一个 Promise。

示例:

按字母顺序对测试路径进行排序。

const Sequencer = require('@jest/test-sequencer').default;
class CustomSequencer extends Sequencer {
  sort(tests) {
    // Test structure information
    // https://github.com/facebook/jest/blob/6b8b1404a1d9254e7d5d90a8934087a9c9899dab/packages/jest-runner/src/types.ts#L17-L21
    const copyTests = Array.from(tests);
    return copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1));
  }
}
module.exports = CustomSequencer;

# testURL [string]

默认: http://localhost

  • 此选项设置 jsdom 环境的 URL。它反映在诸如 location.href .

# timers [string]

默认值︰ real

  • 将此值设置为 fake 允许对诸如 setTimeout . 当一段代码设置了我们不想在测试中等待的长时间超时时,假计时器很有用。

# transform [Object<string,pathToTransformer | [pathToTransformer, Object]>]

默认值: undefined

  • 从正则表达式到转换器路径的映射。转换器是一个为转换源文件提供同步功能的模块。例如,如果您希望能够在模块或测试中使用 node 尚不支持的新语言功能,您可以插入将未来版本的 JavaScript 编译为当前版本的众多编译器之一。示例:请参阅示例 / 打字稿示例或 webpack 教程

此类编译器的示例包括:

  • 通天塔
  • 打字稿
  • 异步生成
  • 要构建您自己的,请访问自定义变压器部分

您可以将配置传递给转换器 {filePattern: ['path-to-transformer', {options}]} ,例如,将 babel-jest 配置为非默认行为, {"\\.js$": ['babel-jest', {rootMode: "upward"}]}

注意:除非文件已更改,否则每个文件只运行一次转换器。 --no-cache 在开发转换器期间,运行 Jest 以经常删除 Jest 的缓存可能很有用。

注意:如果您正在使用 babel-jest 转换器并想使用额外的代码预处理器,请记住,当 “转换” 以任何方式被覆盖时, babel-jest 不再自动加载。如果你想用它来编译 JavaScript 代码,它必须被显式定义。参见 babel-jest 插件

# transformIgnorePatterns [array<string>]

默认值︰ ["node_modules"]

  • 在转换之前与所有源文件路径匹配的正则表达式模式 string array。如果测试路径匹配任何模式,它将不会被转换。

  • 这些模式 string 与完整路径匹配。使用 <rootDir> string 标记来包含项目根目录的路径,以防止它意外忽略可能具有不同根目录的不同环境中的所有文件。

示例: ["<rootDir>/bower_components/", "<rootDir>/node_modules/"]

有时会发生(尤其是在 React Native 或 TypeScript 项目中)第 3 方模块以未转译的形式发布。由于默认不转换里面的所有文件 node_modules ,所以 Jest 不会理解这些模块中的代码,从而导致语法错误。为了克服这个问题,您可以使用 transformIgnorePatterns 将此类模块列入白名单。你会在 React Native Guide 中找到这个用例的一个很好的例子。

# unmockedModulePathPatterns [array<string>]

默认值: []

  • 在模块加载器将自动为它们返回一个模拟之前,与所有模块匹配的正则表达式模式 string array。如果模块的路径与此列表中的任何模式匹配,则模块加载器不会自动模拟它。

  • 这对于一些常用的 “实用程序” 模块很有用,这些模块几乎总是几乎一直用作实现细节(如下划线 / 低破折号等)。通常最好的做法是让这个列表尽可能的小,并且总是在单独的测试中使用显式的 jest.mock() / jest.unmock() 调用。显式的每个测试设置对于测试的其他读者来说更容易推断测试将在其中运行的环境。

  • jest.mock() 可以通过在测试文件顶部显式调用来覆盖单个测试中的此设置。

# verbose [boolean]

默认值︰ false

  • 指示是否应在运行期间报告每个单独的测试。执行后,所有错误也仍会显示在底部。

# watchPathIgnorePatterns [array<string>]

默认值: []

  • 在监视模式下重新运行测试之前,与所有源文件路径匹配的 RegExp 模式 array。如果文件路径与任何模式匹配,则在更新时不会触发重新运行测试。

  • 这些模式与完整路径匹配。使用 <rootDir> string 标记来包含项目根目录的路径,以防止它意外忽略可能具有不同根目录的不同环境中的所有文件。示例: ["<rootDir>/node_modules/"]

# watchPlugins [array<string | [string,Object]>]

默认值: []

  • 此选项允许您使用自定义手表插件。在此处阅读有关手表插件的更多信息。

手表插件的示例包括:

注意: watchPlugins 属性值中的值可以省略 jest-watch- 包名的前缀。

# // [string]

无默认值

  • 此选项允许在 package.json . 将注释文本作为此键的值包含在 package.json .

示例:

{
  "name": "my-project",
  "jest": {
    "//": "Comment goes here",
    "verbose": true  }
}