热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

起步测试到底测什么提到测试的时候,即使是最简单的一个代码块可能都让初学者不知所措。最常问的问题的是“我怎么知道要测试什么?”。如果你正在写一个Web
起步

测试到底测什么

提到测试的时候,即使是最简单的一个代码块可能都让初学者不知所措。最常问的问题的是“我怎么知道要测试什么?”。如果你正在写一个 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: [// ""// ],// 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,运行转换之后的测试用例代码。


推荐阅读
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • 本文介绍了如何使用elementui分页组件进行分页功能的改写,只需一行代码即可调用。通过封装分页组件,避免在每个页面都写跳转请求的重复代码。详细的代码示例和使用方法在正文中给出。 ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 本文介绍了如何使用vue-awesome-swiper组件,包括在main.js中引入和使用swiper和swiperSlide组件,以及设置options和ref属性。同时还介绍了如何在模板中使用swiper和swiperSlide组件,并展示了如何通过循环渲染swipes数组中的数据,并使用picUrl属性显示图片。最后还介绍了如何添加分页器。 ... [详细]
  • uniapp开发H5解决跨域问题的两种代理方法
    本文介绍了uniapp开发H5解决跨域问题的两种代理方法,分别是在manifest.json文件和vue.config.js文件中设置代理。通过设置代理根域名和配置路径别名,可以实现H5页面的跨域访问。同时还介绍了如何开启内网穿透,让外网的人可以访问到本地调试的H5页面。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • 先看看ElementUI里关于el-table的template数据结构:<template><el-table:datatableData><e ... [详细]
author-avatar
宛岸
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有