Jest 学习01 - Jest 介绍、快速体验、vscode 智能提示、配置、监视模式、Babel 配置

起步

测试到底测什么

提到测试的时候,即使是最简单的一个代码块可能都让初学者不知所措。最常问的问题的是“我怎么知道要测试什么?”。如果你正在写一个 Web 应用,那么依次测试每个页面的用户交互方式,就是一个很好的开端了。

但 Web 应用也是由很多个函数和模块组成的代码单元,也是需要测试的。通常有两种情况:

  • 你接手的遗留代码没有写测试用例
  • 你必须从无到有的实现一个新功能

对于上面两种场景,你可以把测试视为代码的一部分来编写。我所说的这些代码,是用来检查给定的函数是否产生预期输出结果的。 一个典型的测试流程如下:

  1. 引入要测试的函数
  2. 给函数一个输入
  3. 定义预期输出
  4. 检查函数是否返回了预期的输出结果

即:输入 —— 预期输出 —— 验证结果

示例

下面来看一个例子:

// math.js
function sum (a, b) {
  return a + b
}

function subtract (x, y) {
  return x - y
}

module.exports = {
  sum,
  subtract
}

如何保证上面代码的正确性?

下面来写一段测试代码:

注意:通常将实际代码与测试文件隔离放置,方便管理维护。

// math.test.js
const { sum, subtract } = require('./math')

// 测试示例1
// 运行结果
const result = sum(1, 2)
// 期望结果
const expected = 3

if (result !== expected) {
  throw new Error(`1 + 2 应该等于 ${expected},但是结果却是 ${result}`)
}

// 测试示例2
// 运行结果
const result2 = subtract(2, 1)
// 期望结果
const expected2 = 1

if (result2 !== expected2) {
  throw new Error(`2 - 1 应该等于 ${expected2},但是结果却是 ${result2}`)
}

通过测试代码可以很方便的帮助验证代码的正确性。

封装测试工具函数

之前示例的测试代码太过繁琐,可以思考一下能否封装的更简便一些,比如下面这样:

expect(sum(1, 2)).toBe(3)
expect(subtract(2, 1)).toBe(-1)

上面的测试代码就像自然语言说话一样,很舒服。

expect 称为断言函数:断定一个真实的结果是期望的结果。很多测试框架都有这个方法。

实现 expect 方法:

expect(sum(1, 2)).toBe(3)
expect(subtract(2, 1)).toBe(1)

function expect(result) {
  return {
    toBe(actual) {
      if (result !== actual) {
        throw new Error(`预期值和实际值不相等,预期 ${result},结果确实 ${actual}`)
      }
    }
  }
}

增加错误提示信息:

// math.test.js
const { sum, subtract } = require('./math')

test('测试加法', () => {
  expect(sum(1, 2)).toBe(3)
})

test('测试减法', () => {
  expect(subtract(2, 1)).toBe(1)
})

function test(description, callback) {
  try {
    callback()
    console.log(`${description} 通过测试`)
  } catch (err) {
    console.error(`${description} 没有通过测试:${err}`)
  }
}

function expect(result) {
  return {
    toBe(actual) {
      if (result !== actual) {
        throw new Error(`预期值和实际值不相等,预期 ${result},结果确实 ${actual}`)
      }
    }
  }
}

Jest 介绍

Jest 是 Facebook 出品的一个 JavaScript 开源测试框架。相对其他测试框架,其一大特点就是就是内置了常用的测试工具,比如零配置、自带断言、测试覆盖率工具等功能,实现了开箱即用。

Jest 适用但不局限于使用以下技术的项目:Babel,、TypeScript、 Node、 React、Angular、Vue 等。

Jest 主要特点:

  • 零配置
  • 自带断言
  • 而作为一个面向前端的测试框架, Jest 可以利用其特有的快照测试功能,通过比对 UI 代码生成的快照文件,实现对 React 等常见前端框架的自动测试。
  • 此外, Jest 的测试用例是并行执行的,而且只执行发生改变的文件所对应的测试,提升了测试速度。
  • 测试覆盖率
  • Mock 模拟

快速体验 Jest

安装 Jest 到项目中:

npm init -y
npm install -D jest

package.json 添加脚本:

"scripts": {
  "test": "jest"
},

编写实际代码:

// math.js
function sum(a, b) {
  return a + b
}

function subtract(x, y) {
  return x - y
}

module.exports = {
  sum,
  subtract
}

编写测试用例:

// math.test.js
const { sum, subtract } = require('./math')

test('测试加法', () => {
  expect(sum(1, 2)).toBe(3)
})

test('测试减法', () => {
  expect(subtract(2, 1)).toBe(1)
})

npm run test 运行测试命令。

在这里插入图片描述

  • Jest 找到项目中所有以 .test.js 结尾的文件并运行
  • Jest 会给测试文件注入 testexpect 等全局函数,所以在测试文件中可以直接使用
  • Jest 为测试结果提供了良好的日志输出

vscode 中 jest 代码智能提示

由于文件中并没有引入 Jest 的方法,所以使用的时候 vscode 没有提供智能提示。

可以通过安装 jest 的类型声明文件 @types/jest 来解决。

npm i -D @types/jest

注意:@types/jest 必须安装到项目的根目录,并且以根目录的方式在 vscode 中打开,否则不生效。

或者说只要是 vscode 打开的项目根目录有 @types/jest 这个包就可以了。

这是因为 TS 是从项目根目录下的 node_modules 查找 @types 类型声明文件的。

在这里插入图片描述

Jest 配置

配置文件

Jest 默认提供了零配置的使用方式。如果要修改默认配置规则,可以生成并修改配置文件。

# 生成 jest 配置文件
npx jest --init

# 配置文件的格式 ts or js
√ Would you like to use Typescript for the configuration file? ... no
# 测试环境 node 环境 或 jsdom 浏览器环境
√ Choose the test environment that will be used for testing » jsdom (browser-like)
# 是否需要 Jest 收集测试覆盖率报告
√ Do you want Jest to add coverage reports? ... no
# 用于统计测试覆盖率使用的引擎
# 目前最稳定是的 babel,v8 仍处于实验阶段,建议 node v14 版本以上使用
√ Which provider should be used to instrument code for coverage? » babel
# 是否在每次测试之前清除 mock 调用和相关实例
√ Automatically clear mock calls, instances and results before every test? ... yes

详细配置信息参考:配置 Jest(中文文档翻译不全,仅供参考)。

生成的配置文件 jest.config.js 中列出了一些配置选项,如果在生成时选择了非默认设置,就会取消注释覆盖默认配置,完整配置项请参考文档。

简单介绍几个:

/*
 * For a detailed explanation regarding each configuration property, visit:
 * https://jestjs.io/docs/configuration
 */

module.exports = {
  // All imported modules in your tests should be mocked automatically
  // 自动 mock 所有导入的外部模块
  // automock: false,

  // Stop running tests after `n` failures
  // 在指定次数失败后停止运行测试
  // bail: 0,

  // The directory where Jest should store its cached dependency information
  // cacheDirectory: "C:\\Users\\Administrator\\AppData\\Local\\Temp\\jest",

  // Automatically clear mock calls, instances and results before every test
  // 在每个测试之间自动清除 mock 调用和实例
  clearMocks: true,

  // Indicates whether the coverage information should be collected while executing the test
  // 是否收集测试覆盖率信息
  // collectCoverage: false,

  // An array of glob patterns indicating a set of files for which coverage information should be collected
  // 一个 glob 模式数组,指示应该为其收集覆盖率信息的一组文件
  // collectCoverageFrom: undefined,

  // The directory where Jest should output its coverage files
  // 测试覆盖率报错文件输出的目录
  // coverageDirectory: undefined,

  // An array of regexp pattern strings used to skip coverage collection
  // 忽略测试覆盖率统计的文件
  // coveragePathIgnorePatterns: [
  //   "\\\\node_modules\\\\"
  // ],

  // Indicates which provider should be used to instrument code for coverage
  // 指示应该使用哪个引擎检测代码的覆盖率,默认是 babel,可选 v8,但是 v8 不太稳定,建议 Node 14 以上版本使用
  // coverageProvider: "babel",

  // A list of reporter names that Jest uses when writing coverage reports
  // coverageReporters: [
  //   "json",
  //   "text",
  //   "lcov",
  //   "clover"
  // ],

  // An object that configures minimum threshold enforcement for coverage results
  // coverageThreshold: undefined,

  // A path to a custom dependency extractor
  // dependencyExtractor: undefined,

  // Make calling deprecated APIs throw helpful error messages
  // errorOnDeprecated: false,

  // Force coverage collection from ignored files using an array of glob patterns
  // forceCoverageMatch: [],

  // A path to a module which exports an async function that is triggered once before all test suites
  // globalSetup: undefined,

  // A path to a module which exports an async function that is triggered once after all test suites
  // globalTeardown: undefined,

  // A set of global variables that need to be available in all test environments
  // globals: {},

  // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
  // maxWorkers: "50%",

  // An array of directory names to be searched recursively up from the requiring module's location
  // moduleDirectories: [
  //   "node_modules"
  // ],

  // An array of file extensions your modules use
  // moduleFileExtensions: [
  //   "js",
  //   "jsx",
  //   "ts",
  //   "tsx",
  //   "json",
  //   "node"
  // ],

  // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
  // moduleNameMapper: {},

  // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
  // modulePathIgnorePatterns: [],

  // Activates notifications for test results
  // notify: false,

  // An enum that specifies notification mode. Requires { notify: true }
  // notifyMode: "failure-change",

  // A preset that is used as a base for Jest's configuration
  // preset: undefined,

  // Run tests from one or more projects
  // projects: undefined,

  // Use this configuration option to add custom reporters to Jest
  // reporters: undefined,

  // Automatically reset mock state before every test
  // resetMocks: false,

  // Reset the module registry before running each individual test
  // resetModules: false,

  // A path to a custom resolver
  // resolver: undefined,

  // Automatically restore mock state and implementation before every test
  // restoreMocks: false,

  // The root directory that Jest should scan for tests and modules within
  // rootDir: undefined,

  // A list of paths to directories that Jest should use to search for files in
  // roots: [
  //   "<rootDir>"
  // ],

  // Allows you to use a custom runner instead of Jest's default test runner
  // runner: "jest-runner",

  // The paths to modules that run some code to configure or set up the testing environment before each test
  // setupFiles: [],

  // A list of paths to modules that run some code to configure or set up the testing framework before each test
  // setupFilesAfterEnv: [],

  // The number of seconds after which a test is considered as slow and reported as such in the results.
  // slowTestThreshold: 5,

  // A list of paths to snapshot serializer modules Jest should use for snapshot testing
  // snapshotSerializers: [],

  // The test environment that will be used for testing
  testEnvironment: "jsdom",

  // Options that will be passed to the testEnvironment
  // testEnvironmentOptions: {},

  // Adds a location field to test results
  // testLocationInResults: false,

  // The glob patterns Jest uses to detect test files
  // 运行 Jest 时运行的测试文件
  // testMatch: [
  //   所有 __tests__ 目录下的 .js .ts .jsx .tsx 文件
  //   "**/__tests__/**/*.[jt]s?(x)",
  //   所有文件名带 .test. 或 .spec. 的 .js .ts .jsx .tsx 文件
  //   "**/?(*.)+(spec|test).[tj]s?(x)"
  // ],

  // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
  // 忽略测试的目录
  // testPathIgnorePatterns: [
  //   "\\\\node_modules\\\\"
  // ],

  // The regexp pattern or array of patterns that Jest uses to detect test files
  // testRegex: [],

  // This option allows the use of a custom results processor
  // testResultsProcessor: undefined,

  // This option allows use of a custom test runner
  // testRunner: "jest-circus/runner",

  // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
  // testURL: "http://localhost",

  // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
  // timers: "real",

  // A map from regular expressions to paths to transformers
  // transform: undefined,

  // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
  // transformIgnorePatterns: [
  //   "\\\\node_modules\\\\",
  //   "\\.pnp\\.[^\\\\]+$"
  // ],

  // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
  // unmockedModulePathPatterns: undefined,

  // Indicates whether each individual test should be reported during the run
  // verbose: undefined,

  // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
  // watchPathIgnorePatterns: [],

  // Whether to use watchman for file crawling
  // watchman: true,
};

Jest CLI

Jest 除了通过配置文件进行配置,还可以通过命令行参数进行配置。

参考:Jest CLI 选项 · Jest (jestjs.io)

有些配置只能在配置文件中使用,有些配置只能在命令行参数中使用,例如监视文件只用使用命令行参数 --watchAll

Jest 监视模式

–watchAll

监视文件的更改并在任何更改时重新运行所有测试。

jest --watchALl

–watch

该模式需要 Git 支持。git init 初始化仓库

监视 Git 仓库中更改的文件,并重新运行与已更改的文件相关的测试。

jest --watch

监视模式中的辅助命令

使用监视模式后,命令行中会显示辅助命令提示:

在这里插入图片描述

Watch Usage
 # 按 a 进入 a 模式:运行所有的测试。
 # a 进入,a 退出
 # 也可以使用 jest --watchAll 直接进入 a 模式
 # 只有 jest --watch 时才能使用
 › Press a to run all tests.
 
 # 按 f 进入 f 模式:只运行失败的测试。
 # f 进入,f 退出
 › Press f to run only failed tests.
 
 # 按 o 进入 o 模式:只运行与更改文件相关的测试。
 # 需要 Git 支持
 # 也可以使用 jest --watch 直接进入 o 模式
 # 只有 jest --watchAll 时才能使用
 › Press o to only run tests related to changed files.
 
 # 按 p 以文件名正则表达式模式进行过滤。
 # 只有 --watchAll 的时候 p 模式才可以使用
 # 注意:testRegex 将尝试使用绝对文件路径来检测测试文件,因此,具有名称与之匹配的文件夹将所有文件作为测试运行
 # testRegex 会忽略 testMatch
 › Press p to filter by a filename regex pattern.
 
 # 按 t 以测试名称(test 方法第一个参数)正则表达式模式进行过滤。
 › Press t to filter by a test name regex pattern.
 
 # 按 q 退出监视模式
 › Press q to quit watch mode.
 
 # 按 Enter 键触发测试运行
 › Press Enter to trigger a test run.

使用 ES6 模块

如果要在 Jest 测试中使用 ES6 模块,则需要使用-babel

# 安装 babel 相关依赖
npm i -D babel-jest @babel/core @babel/preset-env
// babel.config.js
module.exports = {
  presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};

Jest 在运行测试的时候会自动找到 Babel 将 ES6 代码转换为 ES5 执行。

Jest 结合 Babel 的运行原理:运行测试之前,结合 Babel,先把代码做一次转化,模块被转换为了 CommonJS,运行转换之后的测试用例代码。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
jest.config.js是用于配置Jest测试框架的文件。它允许你自定义Jest的行为和设置,以满足你的项目需求。下面是一些常见的配置选项: 1. `preset`: 用于指定预设配置,可以是一个字符串或一个包含配置选项的对象。预设配置可以帮助你快速设置常见的测试环境,例如`@vue/cli-plugin-unit-jest`用于Vue项目。 2. `testEnvironment`: 指定测试运行的环境,默认为`jsdom`,可以是`node`、`jsdom`或者自定义的环境。 3. `testMatch`: 指定要运行的测试文件的匹配模式,默认为`**/__tests__/**/*.[jt]s?(x)`。你可以根据自己的项目结构和命名规范来修改。 4. `moduleFileExtensions`: 指定模块文件的扩展名,默认为`['js', 'json', 'jsx', 'ts', 'tsx', 'node']`。如果你的项目使用了其他扩展名的文件,可以在这里添加。 5. `transform`: 配置文件转换器,用于将不同类型的文件转换为可执行的JavaScript代码。例如,使用`babel-jest`可以将ES6代码转换为ES5代码。 6. `coverageThreshold`: 配置代码覆盖率的阈值,可以设置全局或每个文件的覆盖率要求。 7. `setupFilesAfterEnv`: 指定在运行测试之前需要执行的文件,可以用于设置全局的测试环境。 8. `snapshotSerializers`: 配置快照序列化器,用于自定义快照的序列化和反序列化过程。 9. `globals`: 全局变量的配置,可以在测试文件中直接使用。 以上是一些常见的配置选项,你可以根据自己的需求进行配置。如果你有具体的问题或需要更详细的介绍,请告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值