Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Jest实战:单元测试与服务测试

Jest实战:单元测试与服务测试

作者头像
心谭博客
发布于 2020-04-21 07:11:41
发布于 2020-04-21 07:11:41
3.5K00
代码可运行
举报
文章被收录于专栏:YuanXinYuanXin
运行总次数:0
代码可运行

需求与解决思路

一名好的大前端开发人员,一定是一名好的“配置工程师”(滑稽脸)。而最近刚到团队,被安排给 vemoJS 和 cloudbase-cli 写测试用例,并且要保证覆盖率!

这里主要以 vemojs 下的测试用例为主来讲解 Jest 要注意的地方。测试代码在:https://github.com/vemoteam/vemo/tree/master/test

观察 vemojs 这个项目,如果想进行全面测试,需要解决以下问题:

  1. 以 utils.js errror.js 等文件,对应的是单元功能测试
  2. 以 cloudbase.js 文件为代表的,需要请求远程 API,模拟不同的情况
  3. 以 index.js 中的 http 和静态服务器为代表的,测试服务是否正常启动
  4. 以 index.js 中的 websocket 服务为代表的,模拟用户使用环境,测试 ws 是否正常
  5. 提供测试覆盖率

针对以上问题,解决思路总结如下:

  1. 函数功能测试:断言匹配功能
  2. 请求 API:mock 模块和函数,例如测试用例中的 axios 就是被 mock 的
  3. http 和静态服务:测试代码中启动服务后,利用 axios 等第三方请求库请求服务
  4. websock 服务:借助 puppeteer(内置无头浏览器)来模拟用户使用,监听数据变动
  5. jest 自带覆盖率统计工具

测试过程

针对上面的步骤以及核心的 jest 配置,分别做讲解。

1. 配置文件和命令行

jest 提供两种方式来让用户自定义配置,一个是根目录的 jest.config.js ,另一个是启动 jest 的时候给参数。我是采用两者混搭的方法。

jest.config.js :在统计覆盖率的时候,忽略 testnode_modules 文件夹下。有时候为了方便,会把测试常用的函数、配置放在 test 目录下,如果不忽略,会被统计进去,但它不属于源码部分。除此之外,别忘了 node_modules,否则由于文件太多,根本启动不起来,而且结果也不对。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
    coveragePathIgnorePatterns: ["/test/", "/node_modules/"]
};

命令行参数写在 package.json 文件的 scripts 属性中。 需要注意的地方有 2 个, --detectOpenHandles 参数是为了当句柄未正常关闭,显式报错给用户; --env=node 指明测试环境是 nodejs,默认是浏览器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  "scripts": {
    "test": "jest --passWithNoTests --coverage --env=node --detectOpenHandles"
  }

2. 断言与函数功能

这个很简单,但是可以配合 describe 关键字,层级区分测试逻辑。还可以配合 beforeAll 等生命周期钩子函数,提高测试效率。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const { VemoError } = require("./../src/error");

describe("error.js", () => {
    test("Throw VemoError", () => {
        function throwVemoError() {
            throw new VemoError();
        }

        expect(throwVemoError).toThrow(Error);
        expect(throwVemoError).toThrow(VemoError);
    });

    test("VemoError should have code and message", () => {
        const properties = ["code", "message"];
        const vemoError = new VemoError();
        expect(properties.every(prop => vemoError.hasOwnProperty(prop))).toBe(
            true
        );
    });
});

3. 远程 API 测试

有一些函数需要连接云的 API 进行认证,由于安全策略,不在云厂商的服务器上无法请求。这时候,就需要 mock 对应的请求库,返回我们构造好的数据,以让函数逻辑走下去,提高测试覆盖率。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
jest.mock("axios");
test("getTempSecret should get tencent cloud temporary secret", async () => {
    // 下面就是mock的数据
    axios.get.mockResolvedValue({
        data: {
            TmpSecretId: "testTmpSecretId",
            TmpSecretKey: "testTmpSecretKey",
            Token: "testToken",
            ExpiredTime: Date.now()
        }
    });

    await cloudBaseMiddleware({}, async () => {});
});

4. http 与 static 服务测试

这方面很多人可能会用 supertest 这个库来测试。在做调研的时候发现,jest 的下载量和更新记录远远高于 supertest,而且更纯粹。为什么这么说呢?它提供一种测试的组织形式,其它可以借助第三方库和工具实现。

而服务测试的思路就是:在 test 目录下启动简单的 http 服务器和静态服务器,然后利用 axios 访问启动的服务器,拿到返回结果,再利用断言的写法,检查即可。

请看下面这段代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
require("./../../src/"); // 启动服务器
// 加载配置文件和axios库
const axios = require("axios");
const config = require("./vemofile");
const instance = axios.create({
    baseURL: `http://${config.host}:${config.port}`
});
// 下面分别请求:/home#GET 和 /api#POST 接口,并且检查返回结果
describe("index.js api server", () => {
    test("template response should be HTML", async () => {
        expect.assertions(2);
        const { data, status } = await instance.get("/home");

        expect(status).toEqual(200);
        expect(data).toMatch(/<html>.*<\/html>/is);
    });

    test("post and validate check", async () => {
        expect.assertions(2);
        const params = {
            param1: "test",
            param2: 123
        };
        const { data, status } = await instance.post("/api", params);

        expect(status).toEqual(200);
        expect(JSON.stringify(data)).toEqual(JSON.stringify(params));
    });
});

5. puppeteer 与无头浏览器

针对 ws 协议,测试它的思路有点像 SSR:

  1. 启动测试后台,并且在 /ws 路由上启动 ws 协议,在 2s 后,会向链接的客户端主动发送消息
  2. puppeteer 打开新的页面,访问对应的页面,拿到页面的内容,并且记录
  3. 新的页面在等待 2s 后,接受到 /ws 主动传来的数据,然后更新页面内容
  4. 再利用 puppeteer 读取页面内容,并且记录
  5. 比较 2 次记录的内容是否有更新,如果有,那么验证通过

具体请看:https://github.com/vemoteam/vemo/blob/master/test/server/index.test.js 的 61 ~ 91 行

体验与改进

1. windows 下的 puppeteer

由于 windows 下 puppeteer 无法通过 npm 下载安装(就是很麻烦),所以把 puppeteer 的加载代码进一步处理,同时在失败的时候给出友好的提示,引导使用者切换测试平台:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// ... other codes
async function launchBrowser() {
    try {
        const puppeteer = require("puppeteer");
        const browser = await puppeteer.launch();
        return browser;
    } catch (error) {
        // if load fail, show information and return immediately
        console.log(
            "Don't run test in Windows. \n" +
                "If you fail to launch on UNIX, please install dependencies. \n" +
                "More info: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md. \n"
        );
        return null;
    }
}

const browser = await launchBrowser();
// ... other codes

2. 最小影响原则

http 服务器、静态服务器和 ws 服务器对应的启动文件 /src/index.js 没有对外暴露接口,没法显示传入要求的配置文件: vemofile.js ,它只能自动读取。

而在运行测试的时候,它会在根目录下读取 vemofile.js ,而我们的配置写在 /test/serve 下,所以要手动切换一下运行目录: process.chdir(__dirname) 。这样就保证了针对测试服务器的配置不会污染代码库。

3. 下载体验

用户在安装库的时候,显然不需要跑测试,所以需要让 npm 忽略 test 目录下的文件(其实对于一些 ts 的项目,src 下的源码也是忽略的)。给 .npmignore 添加如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# test
test

测试效果

最后放一下覆盖率统计效果吧(Ubuntu 16.04):

没覆盖的地方,全部是出现异常地方。一般来说超过 80%的覆盖率即可,其他的可以慢慢补上。这种自己手动跑的方式太 low 了,之后还会有一篇讲解 CI 等第三方工具的文章,“懒就是生产力”。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用jest进行单元测试
不扯犊子直接说吧,第一点,用数据、用茫茫多的测试用例去告诉使用者,你的程序是多么鲁棒健壮;第二点,把它作为一种素养去培养吧,当你按照一系列规范去做事,那么你做出来的东西,我想是有品质在的。
江涛学编程
2020/08/25
3.9K0
使用jest进行单元测试
前端单元测试那些事
Jest 是 Facebook 开源的一款 JS 单元测试框架,它也是 React 目前使用的单元测试框架,目前vue官方也把它当作为单元测试框架官方推荐 。 目前除了 Facebook 外,Twitter、Airbnb 也在使用 Jest。Jest 除了基本的断言和 Mock 功能外,还有快照测试、实时监控模式、覆盖度报告等实用功能。 同时 Jest 几乎不需要做任何配置便可使用。
树酱
2020/07/03
4.7K0
前端单元测试那些事
单元测试
测试的目的是为了带给我们带来强大的代码信心,如果把测试初衷忘掉,会很容易掉入测试代码细节的陷阱。一旦关注点不是代码的信心,而是测试代码细节,那么测试用例会变得非常脆弱,难以维护。
用户4619307
2024/01/12
8030
web前端好帮手 - Jest单元测试工具
本文介绍如何使用Jest覆盖Web前端单元测试、如何统计测试覆盖率,Jest对比Mocha等内容。 Jest是什么? Jest是一个令人愉快的 JavaScript 测试框架,专注于简洁明快。 正如官方介绍所说,Jest是一款开箱即用的测试框架,其中包含了Expect断言接口、Mock接口、Snapshot快照、测试覆盖率统计等等全套测试功能。 为什么不推荐Mocha? 不支持原生并行测试 断言库要另外安装 测试覆盖率统计功能要另外安装 原生输入的测试报告可读性很差,格式化也要另外安装 不支持snap
QQ音乐技术团队
2020/06/15
5.3K0
Jest单元测试之旅—实践总结
维基百科对于单元测试的定义:是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。
gary12138
2022/10/05
10.8K0
Jest单元测试之旅—实践总结
一杯茶的时间,上手 Jest 测试框架
现在让我们正式开始,茶和图雀社区精心准备的甜品更搭哦。 在项目根目录下新建src目录,存放我们的功能代码。然后创建src/dessert.js。
一只图雀
2020/04/13
2K0
前端自动化测试实践03—jest异步处理&mock
一般项目代码中会有不少异步 ajax 请求,例如测试下面 async.js 中的代码
CS逍遥剑仙
2019/10/31
5.4K0
那些年错过的React组件单元测试(上)
关于前端单元测试,其实两年前我就已经关注了,但那时候只是简单的知道断言,想着也不是太难的东西,项目中也没有用到,然后就想当然的认为自己就会了。
前端森林
2021/04/12
5.4K0
Jest 单元测试快速上手指南
执行 yarn jest 或者 yarn jest test/plus.spec.js 运行测试用例
木子星兮
2020/08/25
3.6K0
Jest 单元测试快速上手指南
使用 Jest 进行前端单元测试
目前 Jest 已经在 Facebook 开源的 React, React Native 等前端项目中被做为标配测试框架。下面简单介绍一些 Jest 比较有用的功能和用法。
QQ音乐技术团队
2018/01/31
5.9K0
使用 Jest 进行前端单元测试
【架构师(第二十七篇)】前端单元测试框架 Jest 基础知识入门
如果使用的是 vscode 并且安装了 jest 插件,那么可以实时并且直观的看到测试是否通过
一尾流莺
2022/12/10
1.4K0
【架构师(第二十七篇)】前端单元测试框架 Jest 基础知识入门
如何做前端单元测试
对于现在的前端工程,一个标准完整的项目,通常情况单元测试是非常必要的。但很多时候我们只是完成了项目而忽略了项目测试。我认为其中一个很大的原因是很多人对单元测试认知不够,因此我写了这边文章,一方面期望通过这篇文章让你对单元测试有一个初步认识。另一个方面希望通过代码示例,让你掌握写单元测试实践能力。
政采云前端团队
2021/12/09
3.6K0
如何做前端单元测试
前端单元测试之Jest
关于前端单元测试的好处自不必说,基础的介绍和知识可以参考之前的博客链接:React Native单元测试。在软件的测试领域,测试主要分为:单元测试、集成测试和功能测试。
xiangzhihong
2022/11/30
3K0
用Jest来给React完成一次妙不可言的~单元测试
在2020的今天,构建一个 web 应用对于我们来说,并非什么难事。因为有很多足够多优秀的的前端框架(比如 React,Vue 和 Angular);以及一些易用且强大的UI库(比如 Ant Design)为我们保驾护航,极大地缩短了应用构建的周期。
用户1462769
2020/03/30
15.4K0
[译] Vuex 之单元测试
原文:https://lmiller1990.github.io/vue-testing-handbook/testing-vuex.html
江米小枣
2020/06/15
3.5K0
【干货分享】微信小程序单元测试攻略
导语 本文作者是腾讯社交增值产品部高级前端工程师林毅雄,对前端开发领域颇有研究。接下来,本文将从测试框架、实战、覆盖率、踩坑等方面分享一下微信小程序的单元测试经验,希望能帮到大家。 01 写作初衷 大家先看看A公司与B公司的数据对比: 从上图可以看出,B公司的单元测试做的比较好,每百行error数也比A公司的项目低。 总体来说,单元测试有以下一些好处: 1,及早发现代码错误,提高代码质量和可维护性。 2,代码变更时可以快速进行检查。 然而要做好测试也有一定的困难: 1,花费时间长。 2,被测代码
WeTest质量开放平台团队
2021/12/17
3.1K0
写代码无BUG,网易云前端单元测试方案总结
单元测试的技术方案很多,不同工具之间有互相协同,也存在功能重合,给我们搭配测试方案带来不小的困难,而且随着 ES6, TypeScript 的出现,单元测试又增加了很多其他步骤,完整配置起来往往需要很大的时间成本。我希望通过对这些工具的各自作用的掌握,了解完整的前端测试技术方案。前端单元测试的领域也很多,这里主要讲对于前端组件如何进行单元测试,最后会主要介绍下对于 React 组件的一些测试方法总结。
秋风的笔记
2021/03/12
10.1K0
写代码无BUG,网易云前端单元测试方案总结
干货 | 携程租车React Native单元测试实践
琨玮,携程高级前端开发工程师,从事React Native/Web前端的开发及维护工作,喜欢研究新技术。
携程技术
2020/02/18
6.6K0
干货 | 携程租车React Native单元测试实践
手写一个简易版 Jest
那当你测试的代码里依赖外部环境的部分,比如要读一个文件、要发送一个请求,这时候怎么测呢?
神说要有光zxg
2024/01/02
2400
手写一个简易版 Jest
前端接入单元测试(Node+React)
假如要重构一个老前端框架,并根据其开发一个向后兼容的新框架。此时老框架针对其内部API函数,写了充分的单侧用例。在开发新框架时,直接运行老前端框架的单侧用例,如果所有测试用例都通过,则可快速保证内部api的一致性,快速验证所有功能。
kiki.
2022/09/29
3.6K0
前端接入单元测试(Node+React)
推荐阅读
相关推荐
使用jest进行单元测试
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验