当前位置: 首页 > news >正文

前端测试最强教程 - 实现 fake http 和 fake db

因为想要写出完美的测试,我们就需要模拟各种接口状态,各种动态数据,要求再高点甚至需要模拟鉴权,那这就不是简单的覆盖方法可以实现的。

所以我们需要一些第三方依赖,下面介绍一下实现步骤。

实现步骤

step 1: 新增业务并进行 case design

为了让便于展示测试,我给网站加了一个新功能,在首页会展示网站的标题并且支持修改,这样就需要一个 get 接口,一个 post 接口,并且还需要数据库。

于是我用 koa 搭了一个后端服务,提供两个接口,数据库我不熟,所以我另辟蹊径,在 notion 上新建了一个 page,通过 notionSDK 来获取和更新 page name,这样就成了我的数据库。

别看我说的简单,其实这一套花了我一个下午,有各种意想不到的问题,比如 koa 如何解析 body、 notion 数据结构太复杂、eslint。

tsconfig 配置的问题等等,期间还错把notion key 给 push 了上去,已经给 disable 了。

 具体怎么实现就不细讲了,这不是本系列教程的重点,代码都在github.com/alpacachen/… ,感兴趣可以自己去看一下 server 目录。

总之最后实现的需求大致长这个样子。

对这个需求进行 case design,得到:


G: 网站加载完成T: 会展示标题 “集成测试框架”W: 点击修改按钮T: 会弹出修改弹窗W: 在输入框中输入 “集成测试框架 2”,点击 “确认修改”T: 弹窗会关闭,网站标题会更新为“集成测试框架 2”

step 2:完善 app-context,支持xhr

install http-request-mock和lokijs 这两个依赖,重写一下 fake-http-handler.ts这个文件

 

import HttpRequestMock from 'http-request-mock';// 引入 mock 请求的依赖import { HupuPostDb, TitleDb } from './fake-db';// 引入提前准备好的 fakedbconst mocker = HttpRequestMock.setup()// mock一下 hupu 接口,数据从写死改为从 db 中读mocker.mock({url: '/hupu/api/v2/bbs/walkingStreet/threads?page=1',method: 'GET',body: { data: { threadList: HupuPostDb.find() } },});// mock 获取标题的请求mocker.mock({url: '/api/title',method: 'GET',response: () => {return TitleDb.findOne().title}});//mo 修改标题的请求mocker.mock({url: '/api/title',method: 'POST',response(req: { body: { title: unknown; }; }) {// 找到并更新const prevTitle = TitleDb.findOne().title;TitleDb.findAndUpdate({ title: prevTitle }, (d) => {d.title = req.body.title})return {};}});

http-request-mock这个依赖应该是国人开发,有优秀的中文文档,大家可以看一下,我就不赘述了github.com/huturen/htt…

新建文件 fake-db.ts


import loki from 'lokijs'import { FakeHupuData } from './fake-data'const db = new loki('fake-db')// 创建虎扑热帖集合const HupuPostDb = db.addCollection('hupu-post')// 插入默认数据HupuPostDb.insert(FakeHupuData)//创建 title 集合const TitleDb = db.addCollection('title')// 插入默认数据TitleDb.insert({ title: '集成测试教程' })export { HupuPostDb, TitleDb }

接下来我们只需要在 app-context.ts中引入一下 fake-http-handler.ts,这样我们的集成测试就支持了接口和数据的库查询修改。

step 3: 根据 case借助 ai 补充新的测试

接下来我们试试在测试跑一遍中调用接口获取数据,修改数据,再次获取最新数据这个流程。

 

describe('W: 点击标题旁边的 修改按钮', () => {beforeEach(() => {fireEvent.click(screen.getByTestId('change-title-but'))})it('T: 会弹出弹窗,input 中展示 “集成测试教程”', () => {expect(screen.getByTestId('title-modal')).toBeTruthy()expect(within(screen.getByTestId('title-modal')).getByDisplayValue('集成测试教程')).toBeTruthy()})describe('W: 修改 title 为 “集成测试教程 2” 关闭弹窗', () => {beforeEach(async () => {const input = within(screen.getByTestId('title-modal')).getByDisplayValue('集成测试教程')fireEvent.change(input, { target: { value: '集成测试教程 2' } })fireEvent.click(screen.getByText('确定修改'))await vi.advanceTimersToNextTimerAsync();})it('T: 弹窗关闭,顶部栏的文案变为“集成测试教程 2”', () => {// headerexpect(screen.queryByTestId('title-modal')).toBeFalsy()expect(screen.getByTestId('header').innerHTML).toContain('集成测试教程 2')})})})

这里需要强调一下,这个测试我是直接接在了之前的测试后面,很方便而且直观,只就是为什么我在第一章的时候强调写测试规范的问题,如果测试规范,是非常易于维护和新增的,会大大降低写测试的压力,从此形成良性循环

step: 4 见真章

直接看npm run test npm run coverage得到结果

可以看到除了 server 的代码还是一片绿,并且也没有加几行测试代码 🎉

大家不妨想一想,如果没有集成测试,依靠单测想要达到这种程度的覆盖率需要写多少代码,多少文件?至少需要 header.test.ts和 store.test.ts两个文件,还要 mock 数据,想想就觉得麻烦。

所以重要的事情说三遍,在前端领域

绝大多数单元测试没有任何卵用

绝大多数单元测试没有任何卵用

绝大多数单元测试没有任何卵用

请不要再写单元测试让你自己和你的同事难受了,集成测试才是王道。

结尾

我们集成测试框架基本完成,麻雀虽小,却五脏俱全。

能看到这里的同学想必一定会有些收获,可以尝试拿着这一套思路去套用到你们当前的项目中,年终绩效就不用愁。毕竟一个能写好测试的前端还是不多见的。

当然我这些代码还是有很多值得优化的点,有一些 corner case 发现了但是没有补充测试。比如文件目录可以更加合理,app-context的代码可以组织的更好。

但是作为一个入门教程我认为达到这个程度就够了,切勿直接套用到生产项目中,我提供的是思路,不是代码。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:【文末自行领取】

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!


http://www.mrgr.cn/news/38293.html

相关文章:

  • 如果你不愿意冒一切风险,就不要成为创业者:如何建立一个年收入 1800 万美元的支付业务
  • Jmeter压测数据库
  • EDA设计:原理、应用与代码实践
  • 2. PH47代码框架二次开发功能特性
  • YOLOv8最新改进2023 CVPR 结合BiFormer
  • 2024淘宝双11活动,收下这份必买好物推荐清单
  • Spring Boot 基础入门指南
  • vector的模拟实现以及oj题(2)
  • SAP员工士气因重组受到打击
  • Android SQLite的基本使用、生成Excel文件保存到本地
  • 面试加分必看,11道接口安全测试面试题!
  • AI跟踪报道第58期-新加坡内哥谈技术-本周AI新闻: OpenAI动荡时刻和Meta从未如此动人
  • 二分查找(2)
  • 耳机检测系统源码分享
  • 手把手教你用PyTorch从零训练自己的大模型(非常详细)零基础入门到精通,收藏这一篇就够了
  • OIDC6-OIDC 授权流程类型
  • 数据特征工程:如何计算块熵?| 基于SQL实现
  • SpringCloud-EurekaClient
  • 继承实现单例模式的探索(一)
  • 探索基因奥秘:汇智生物如何利用组蛋白甲基化修饰测序技术革新农业植物基因组研究?