Nguồn: Cách bắt đầu kiểm tra đơn vị mã JavaScript của bạn,Người viết: Ondrej Polesny
我们 都 应该 测试 , , , , , , , , , , , , , , , ,单元测试还有其他好处吗?
在 篇 , 解释 解释 , , , 单元 测试 带来 带来 带来 好处 好处
不同类型的测试
在 我们 了解 的 , , , , 类型 类型 做 做 做 做 做 做 做 一 快速 快速 快速 快速 快速 介绍
单元测试
单元 测试 你 , , , , , , , , , , , , , 的 的 的 的 ,
export function getAboutUsLink(language){
switch (language.toLowerCase()){
case englishCode.toLowerCase():
return '/about-us';
case spanishCode.toLowerCase():
return '/acerca-de';
}
return '';
}
集成测试
在某些时候,你的代码与数据库、文件系统或其他第三方进行。它甚至可能是你应用程序嗦
这 这 实现 集成 集成 , , , , , , , , , , , ,
功能测试
单元 和 测试 你 你 程序 可以 功能 功能 的 的 的 的 角度 来 来 来 , , , , , ,
在 在 在 在 最 的 的 东西 , , , , , , 自动 自动 自动 自动 执行 执行 执行 执行 执行 执行 执行 执行 执行 执行 执行 执行 执行 的 的
所以现在让我们更详细地了解一下单元测试。
我为什么要写单元测试?
每 当 开发者 他们 的 , , , 告诉 告诉 我 : “
所以 礼貌 笑 , , 他们 想 告诉 你 的 事情 事情 单元 不仅仅 是 为了 测试。 它们 也 在 其他 其他 其他 其他 方面 , , 所以 你 :
对你的代码工作有信心。 你上次提交代码修改,构建失败,一半的应用程序停止工作是什么时候?我的是上周。
但那还是可以的。真正的问题是,当构建成功,改变被部署,你的应用程序开始不稳定。
当 当 当 当 , , , 应用 能够 能够 能够 能够 能够 问题 问题 问题 问题 问题 问题 问题 问题 问题 并 并 并 并 并 并 并 并
做出更好的架构决定。 代码会发生变化,但关于平台、模块、结构等的一些决定需要在项目的早期阶段做出。
当 当 当 当 当 , , , , ,。。 你 会 会 会 因为 因为 因为 因为 因为是单元测试的恶梦。
在编码之前, , , , , , , , 值 值 超出 范围 范围 是 是 是 是 抛出 抛出 是 是 抛出 是 抛出 抛出 抛出异常还是返回null?
单元测试将帮助你发现所有这些情况。再看一下这些题,你会发现这正是定义你的单元测寕寚
我相信写单元测试还有很多好处。这些只是我从验中回忆起来的。那些是过艰苦嚄的
如何编写你的第一个JavaScript 单元试
但是 但是 但是 但是 但是 但是 , 是 一 个 测试 测试 有 有 有 地 地 地 地 地 地 地 地 模拟Studio Code đã được phát hành.
还有其他的框架,如果你感兴趣,你可以在 本文 中查看它们。
npm i jest --save-dev
Hãy sử dụng phương pháp đã đề cập trước đó getAboutUsLink
như một triển khai, chúng tôi muốn thử nghiệm:
const englishCode = "en-US";
const spanishCode = "es-ES";
function getAboutUsLink(language){
switch (language.toLowerCase()){
case englishCode.toLowerCase():
return '/about-us';
case spanishCode.toLowerCase():
return '/acerca-de';
}
return '';
}
module.exports = getAboutUsLink;
我把它放在index.js
文件中。我们可以在同一个文件中写测试,但一个好的做法是将单元测试分离到一个专门的专
常见的命名模式包括{filename}.test.js
和{filename}.spec.js
。我使用了第一种,index.test.js
:
const getAboutUsLink = require("./index");
test("Returns about-us for english language", () => {
expect(getAboutUsLink("en-US")).toBe("/about-us");
});
首先,我们需要导入我们要测试的函数。每个测试都被定义为对 test
函数 的 第一 , , , ,。 另 , , , , , , , , 这里 这里 调用 调用 调用
在这个例子中,我们调用 getAboutUsLink
函数,语言参数为 en-US
。我们期望的结果是 “/about-us”。
Giới thiệu về Jest CLI:
npm i jest-cli -g
jest
如果你看到一个与配置有关的错误,确保你有 package.json
文件。如果你没有,可以用 npm init
生成一个。
你应该看到类似这样的东西:
PASS ./index.test.js
√ Returns about-us for english language (4ms)
console.log index.js:15
/about-us
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.389s
很 很 很 很 很 很 的 你 个 文件 , , , 就 , 扩展 扩展 扩展 测试 测试 测试 测试 测试 测试 测试 测试:
expect(getAboutUsLink("cs-CZ")).toBe("/o-nas");
一旦你保存文件,Jest就会通知你测失败。这有助于你在提交修改之前就发现潜在的问题。
测试高级功能和 Mocking(模拟) 服务
在 在 , , , , , 个 个 个 个 它们 项目 , , 被 被 被 被 被 使用 使用 使用 使用 使用 使用 使用 使用 使用函数中。
import { englishCode, spanishCode } from './LanguageCodes'
你 用 的 这些 常量 中。 要 要 处理 不 不 不 是 简单 的 , , , 情况 会 会 更加 复杂 复杂 这个 : :
import { UserStore } from './UserStore'
function getUserDisplayName(){
const user = UserStore.getUser(userId);
return `${user.LastName}, ${user.FirstName}`;
}
这个方法使用了导入 UserStore
:
class User {
getUser(userId){
// logic to get data from a database
}
setUser(user){
// logic to store data in a database
}
}
let UserStore = new User();
export { UserStore }
为了正确地单元测试这个方法,我们需要 mock(模拟) UserStore
。 Mock 是 对象 一 替代品 它 我们 和 和 和 测试 测试 的 的 , , , , , , , , , , 是 是 是 是 是
如果 我们 , , , 会 同时 这。。 一 , , , , , , , , ,
Mocking(模拟) 一个服务
为了 mock (模拟) , 你 提供 一 个 函数 或 一 一 我 我 , , , , , , , , 可以 可以
jest.mock('./UserStore', () => ({
UserStore: ({
getUser: jest.fn().mockImplementation(arg => ({
FirstName: 'Ondrej',
LastName: 'Polesny'
})),
setUser: jest.fn()
})
}));
首先,我们需要指定我们 giả (模拟) 的是什么 – ./UserStore
模块。接下来,我们需要返回包含该模块所有导出对象的模拟。
在这个例子中,只有名为UserStore
的 User
对象和 getUser
函数。但在真正的实现中,模拟对象可能更长。在单元测试的范围内,任何你并不真正关心嚄台 jest.fn()
轻松地 Mock(模拟)。
函数 getUserDisplayName
的单元测试与我们之前创建的类似:
test("Returns display name", () => {
expect(getUserDisplayName(1)).toBe("Polesny, Ondrej");
})
当 我 , , , 告诉 两 个 通过。 如果 你 手动 执行 , , , , , 现在 就 就 就 , , , , 你 你 看到 的 的 结果 结果 结果 结果
Báo cáo bảo hiểm mã
现在 现在 现在 现在 现在 现在 代码 代码。 说 , , , 而 而 而 而 而 而 而 而 而 而 而 而产生一些无意义的工作量,我们往往会本能的忽略。代码覆盖率统计工具是一个帮助我们兆抗肧
代码覆盖率会告诉你,你的代码有多大一部分被单元测试覆盖。以我的第单元测试为例getAboutUsLink
函数:
test("Returns about-us for english language", () => {
expect(getAboutUsLink("en-US")).toBe("/about-us");
});
它检查了英文链接,但西班牙文版本仍未被测试。代码覆盖率为50%。另一个单元测试是彻底检查 getDisplayName
函数 , 代码 为 为 为 , , , 代码 代码 覆盖率 是。。。。 我们 个 3 个 用 用 例 例 需要 , , , , , 我们 我们 的
要查看代码覆盖率报告,请在终端输入以下命令:
jest --coverage
Bạn có thể sử dụng phần mềm Jest để tạo mã Visual Studio Code, phần mềm quản lý trực quan (CTRL+SHIFT+P)Jest。 触发执行 Phủ sóng。它将在实现中直接显示哪些代码行没有被测试覆盖。
通过运行覆盖率检查,Jest还将创建一个HTML报告。在你的项目文件夹中的coverage/lcov-report/index.html
下找到它。
现在,我不用再提了,你应该争取100%的代码覆盖率,对吗? 🙂
总结
在 这 , , 你 中 中 中 中 中 开始 开始 开始 开始 虽然 报告 报告 报告 , )达到这个目标。我们的目标是让单元测按目助你维护你的代码,并确保它总是按照腧胂宽僽你:
- 明确定义实现需求
- 更好地设计你的代码和分离关注点
- 发现你在较新的提交中尽早发现问题
- 并让你相信你的代码是正常工作的
Bắt đầu (Jest) (入门)
你对测试代码有自己的经验吗?我很想听听,请在 Twitter 上告诉我,或者加入我的 Các luồng Twitch 直播频道。