起步

测试到底测什么

提到测试的时候,即使是最简单的一个代码块可能都让初学者不知所措。最常问的问题的是“我怎么知道要测试什么?”。如果你正在写一个 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 = 3if (result !== expected) {throw new Error(`1 + 2 应该等于 ${expected},但是结果却是 ${result}`)
}// 测试示例2
// 运行结果
const result2 = subtract(2, 1)
// 期望结果
const expected2 = 1if (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 testingtestEnvironment: "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,运行转换之后的测试用例代码。

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

  1. Servlet和HTTP请求协议-学习笔记01【Servlet_快速入门-生命周期方法、Servlet_3.0注解配置、IDEA与tomcat相关配置】

    Java后端 学习路线 笔记汇总表[黑马程序员] Servlet和HTTP请求协议-学习笔记01[Servlet_快速入门-生命周期方法.Servlet_3.0注解配置.IDEA与tomcat相关配置 ...

  2. Koa 学习 01 Koa 介绍和基本使用(路由、静态资源托管、中间件)

    Koa 介绍 Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造,致力于成为 web 应用和 API 开发领域中的一个更小.更富有表现力.更健壮的基石. 官网:https://k ...

  3. Gatsby 学习 - 01 Gatsby 介绍、创建页面

    本文 Gatsby 版本为 v3. Gatsby 介绍 Gatsby 是一个基于 React 的静态站点生成器. Gatsby 通过 React 开发应用,当应用开发完成后,Gatsby 可以把这个 ...

  4. vscode智能提示css的插件_Visual Studio Code 必备插件,主题及语法提示

    Visual Studio Code 是由微软开发的一款免费的,跨平台文本编辑器.由于其出色的性能表现和丰富的功能,它很快成为了开发者的最爱. 与大多数 IDE 一样,VSCode 也有一个扩展市场, ...

  5. 使用 Go module 后 VScode 智能提示不生效解决方案

    关闭 Use Language Server 如果你对这个选项有打钩先取消,然后重启 vscode . 安装 gocode go install github.com/stamblerre/gocod ...

  6. vscode 智能提示失效

    今天正愉快的在开发,突然发现vscode没有提示了,强迫症的我不解决这个问题就不敲代码

  7. vscode 智能打印_vscode智能提示

    vscode智能提示官方版支持部分的语法高亮,现在官方C++插件更新比较快, Visual Studio for C / C++代码的扩展增加了C / C++在Visual Studio语言支持. v ...

  8. vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍

    这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...

  9. JDBC学习笔记01【JDBC快速入门、JDBC各个类详解、JDBC之CRUD练习】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

最新文章

  1. oracle socket读取超时,设置套接字操作超时
  2. JAVA——仿Linux命令行文件管理系统命令的简单实现
  3. unity鼠标控制镜头旋转_Unity3D实现鼠标控制视角转动|chu
  4. nodejs之express入门
  5. 牛客题霸 [反转字符串] C++题解/答案
  6. mysql 撤销权限_MySQL撤销权限(Revote语句)
  7. HDU1202 The calculation of GPA【水题】
  8. hive left join入门
  9. Android ImageSwitcher 配合Picasso解决内存溢出(OOM)问题
  10. 网外(Internet)访问代理服务器内部的实现方法
  11. Go 程序是如何编译成目标机器码的
  12. x黑客X档案2006年07期
  13. 安信可 Telink_825x 环境搭建
  14. 做互联网最重要的是希望! 【水木周平】
  15. 孙子兵法——02 作战第二
  16. Android中文件的读写---assets和raw下的资源文件
  17. 学习1010种热图绘制方法
  18. 睡眠的一场革命!-读《睡眠革命》笔记(下)
  19. ubuntu 安装tar.gz文件
  20. 不能面对的问题还是在逃避

热门文章

  1. 如何解决编程中Excel不能读取的问题
  2. Scrapy基础 第二节:Scrapy版的Hello World
  3. JavaScript实现发送短信验证码
  4. Linux格式化显示json工具jq
  5. 【PaperReading】Toward a gold standard for benchmarking gene set enrichment analysis
  6. 看小镇做题人的悲歌 百感交集
  7. PS-文字如何竖排版
  8. VSCode行内样式没有智能提示
  9. APAP-基础知识(内表SORT的使用)
  10. 项目管理之项目的进度计算问题