你一个开发还搞不懂测试?速来🔥
你们有没有发现现在的测试开发,啥都会,前后端都能写!!! 经常遇到测试同学有 KPI,自己用 Python 或者 Java + Vue 去搞一些内部平台,遇到不会的,找熟悉的开发
# 一、前言
问 xdm 一个问题:你们有没有发现现在的测试开发,啥都会,前后端都能写!!!
经常遇到测试同学有 KPI,自己用 Python 或者 Java + Vue 去搞一些内部平台,遇到不会的,找熟悉的开发同学看一些问题。或者这就是内卷新高度?
但是该学还是学,人家卷我,我不能不卷人家。 作为前端,过去的我不懂单测、不懂接口自动化、UI 自动化,毕竟都在写业务代码,很少去关心这些东西。编程范式里面就有一种测试驱动编程的思想,搞了一段时间的测试后,个人感觉对编码的习惯,影响还是比较大的。
# 二、测试模式
# 2.1 测试驱动编程 TDD
测试驱动开发(英语:Test-driven development,缩写为 TDD)是一种软件开发过程 (opens new window)中的应用方法,由极限编程 (opens new window)中倡导,以其倡导先写测试程序,然后编码实现其功能得名。测试驱动开发始于 20 世纪 90 年代。测试驱动开发的目的是取得快速反馈并使用“illustrate the main line”方法来构建程序。
TDD 也有三层含义:
- Test-Driven Development,测试驱动开发。
- Task-Driven Development,任务驱动开发,要对问题进行分析并进行任务分解。
- Test-Driven Design,测试保护下的设计改善。TDD 并不能直接提高设计能力,它只是给你更多机会和保障去改善设计。
简单说,就是先写测试代码,再写功能
# 2.2 行为驱动开发 BDD
行为驱动开发(英语:Behavior-driven development,缩写BDD)是一种敏捷软件开发 (opens new window)的技术,它鼓励软件项目中的开发者、QA (opens new window)和非技术人员或商业参与者之间的协作。BDD 最初是由 Dan North 在 2003 年命名[1] (opens new window),它包括验收测试和客户测试驱动等的极限编程 (opens new window)的实践,作为对测试驱动开发 (opens new window)的回应。在过去数年里,它得到了很大的发展[2] (opens new window)。
简单说,BDD 就是 TDD 的升级版。BDD 将逻辑部分简单和自然化,用自然语言来描述,让开发、测试以及客户都能看得懂,让大家的行为保持一致
# 2.3 领域驱动设计 DDD
领域驱动设计(英语:domain-driven design,缩写 DDD)是软件代码的结构及语言(类别名称、类方法、类变量)需符合业务领域 (opens new window)中的习惯用法。例如处理租赁业务的软件,其类型可以命名为 LoanApplication 及 Customer,其方法可以用 AcceptOffer 及 Withdraw。领域驱动设计的前提是:
- 把项目的主要重点放在核心领域(core domain)和域逻辑
- 把复杂的设计放在有界域(bounded context)的模型上
- 发起一个创造性的合作之间的技术和域界专家以迭代地完善的概念模式,解决特定领域的问题
简单说就是针对不同领域,独立的去设计某些架构。这个和测试相关度不大,了解下
# 三、测试分类
# 1、单元测试
在计算机编程 (opens new window)中,单元测试(英语:Unit Testing)又称为模块测试 [来源请求] (opens new window) ,是针对程序模块 (opens new window)(软件设计 (opens new window)的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程 (opens new window)中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。
如果你正在使用函数式编程,一个单元最有可能指的是一个函数。你的单元测试将使用不同的参数调用这个函数,并断言它返回了期待的结果。
把代码看成一个个组件,对每个组件进行单独测试,组件内每一个函数的返回结果(或者 dom 的结构)是不是和期望值一样。一般基础库或者组件库都是必须要写的,不然新功能的上线可能就会导致不可预期的功能异常。
# 2、e2e 端到端测试
E2E(end to end)端到端测试是最直观可以理解的测试类型。在前端应用程序中,端到端测试可以从用户的视角通过真实浏览器自动检查应用程序是否正常工作。
E2E 把整个系统当作一个黑盒,测试人员模拟真实用户在浏览器中操作 UI,测试在真实浏览器环境运行测试,测试出的问题可能是前端也可能是后端导致的
- 优点: 真实的测试环境,相比集成测试和单元测试,更容易获得程序的信心
- 缺点: 端到端测试运行不够快,调试比较困难
简单说,就是 UI 自动化测试,反复需要人点击测试的流程,可以用脚本代替。然后针对最终的结果做断言,看是否符合要求
# 四、实现
# 4.1 实现单元测试
- vue2 + jest + vue-test-util 实现可参考这篇:一篇文章学会 Vue 项目单元测试 (opens new window)
- vue3 + vitest 实现可参考这篇:2022 了,试试 Vitest 写写单测(含 Demo 和总结) (opens new window)
笔者偷懒,没动手。。。
# 4.2 实现 e2e
- puppeteer (opens new window) [star 78k]
活跃度高,社区资料丰富,对于前端易用性很强 - phantomJs (opens new window) [star 29k]
已经停止维护,并且环境安装复杂 - selenium (opens new window)[star 24k]
元老框架 虽然依然维护 但是相比 puppeteer 上手速度较慢 文档易读性较差
基于HTTP协议(单向通讯)
- playwright (opens new window) [star 40k]
- 微软出品,必属 XX
- 可直接通过开发者工具和浏览器交互,测试更方便
- 基于 Websocket(双向通讯)可自动获取浏览器实际情况
- 缺点:不兼容老的 Edge 和 IE11,移动端使用模拟器模式,无真机环境
# UI 自动化
- 默认情况下,Playwright 以无头模式运行。如果您想在执行测试时实际看到浏览器,请在启动调用中将 headless 设置为 false
- playWright 官方文档 全英文 (opens new window)
- playWright 中文简版 (opens new window)
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://www.baidu.com/');
await page.screenshot({ path: `example.png` });
await browser.close();
})();
2
3
4
5
6
7
8
9
# 自动脚本生成
# 安装playwright库
pip install playwright
# 安装浏览器驱动文件
python -m playwright install
#再安装
playwright install
# 一键执行,生成自动化脚本
playwright codegen --target javascript -o 'my.ts' -b chromium https://www.baidu.com
2
3
4
5
6
7
8
生成的代码
const { chromium } = require("playwright");
(async () => {
const browser = await chromium.launch({
headless: false,
});
const context = await browser.newContext();
// Open new page
const page = await context.newPage();
// Go to https://www.baidu.com/
await page.goto("https://www.baidu.com/");
// Click input[name="wd"]
await page.locator('input[name="wd"]').click();
// Fill input[name="wd"]
await page.locator('input[name="wd"]').fill("测试e");
// Press Enter
await page.locator('input[name="wd"]').press("Enter");
await page.waitForURL(
"https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E6%B5%8B%E8%AF%95e&fenlei=256&rsv_pq=84e026d700006dfd&rsv_t=1a29OIblO8bE9AtsV2LQygiz3F2VbgmOfn4Frnxu%2BLDIRsnzAJ4Bmt%2BF1lwA&rqlang=en&rsv_enter=1&rsv_dl=tb&rsv_sug3=6&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&rsv_btype=i&prefixsug=%25E6%25B5%258B%25E8%25AF%2595e&rsp=5&inputT=3167&rsv_sug4=5382"
);
// Click text=百度一下
await page.locator("text=百度一下").click();
await page.waitForURL(
"https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&ch=&tn=baidu&bar=&wd=%E6%B5%8B%E8%AF%95e&fenlei=256&oq=%E6%B5%8B%E8%AF%95e&rsv_pq=8931c4b900027d13&rsv_t=f346r8rvlWcVO4rv7PR1Kx1kJDSFbGZ96r4qj9sPt4i%2F2acqT9nlPIG98OI&rqlang=cn"
);
// Click text=百度一下
await page.locator("text=百度一下").click();
// Click input[name="wd"]
await page.locator('input[name="wd"]').click();
// Fill input[name="wd"]
await page.locator('input[name="wd"]').fill("测试e2e");
// Press Enter
await page.locator('input[name="wd"]').press("Enter");
await page.waitForURL(
"https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E6%B5%8B%E8%AF%95e2e&fenlei=256&oq=%25E6%25B5%258B%25E8%25AF%2595e&rsv_pq=96ce991300020017&rsv_t=6db1rU0eGQZ0CtmFHatuznGGgJFdXBsa%2F%2Buuog0HI0QeSEzUDHonLRbilwM&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=3&rsv_sug1=3&rsv_sug7=100&rsv_sug2=0&rsv_btype=t&inputT=2901&rsv_sug4=4038&bs=%E6%B5%8B%E8%AF%95e&rsv_jmp=fail"
);
// Click text=怎么为大中型的vue.js项目编写e2e测试? - 知乎
const [page1] = await Promise.all([
page.waitForEvent("popup"),
page.locator("text=怎么为大中型的vue.js项目编写e2e测试? - 知乎").click(),
]);
// Close page
await page1.close();
// Close page
await page.close();
// ---------------------
await context.close();
await browser.close();
})();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 五、写 or 不写
- 业务型项目,大部分同学应该是没时间写,但是可以带着方便测试的思维去写代码,如果空闲,可以把测试相关代码补上
- 组件库 / 基础库 / 底层框架类项目 不得不写,不然随便一个 breake change,可能影响到的东西,不可预估
# 六、往期回顾
- 超极速的 Vue3 上手指北 🔥 (opens new window) 50+ 👍🏿
- 聊一聊 web 图片小知识 (opens new window) 50+ 👍🏿
- 【逃离一线】被裁后的面经与感慨 (opens new window) 350+ 👍🏿
- 一篇搞定【web 打印】知识点 (opens new window) 90+ 👍🏿
- 一篇够用的 TypeScript 总结 (opens new window) 800+ 👍🏿
- 一名 vueCoder 总结的 React 基础 (opens new window) 240+ 👍🏿
- Vue 转 React 不完全指北 (opens new window) 900+ 👍🏿
- 跳槽人速来,面经&资源分享 (opens new window) 1300+ 👍🏿
- 一年半前端人的求职路 (opens new window) 350+ 👍🏿
- vue2.x 高阶问题,你能答多少 (opens new window) 500+ 👍🏿
- 聊一聊前端性能优化 (opens new window) 1700+ 👍🏿
- Egg + Puppeteer 实现 Html 转 PDF(已开源) (opens new window) 70+ 👍🏿
# 七、参考
- 单元测试到底是什么?应该怎么做?腾讯技术工程的回答 (opens new window)
- 微软开源最强 Python 自动化神器 Playwright!不用写一行代码!自动生成代码还竟然如此流畅!妈妈再也不用担心我不会写代码了! (opens new window)
- 浅谈前端自动化测试 - e2e 篇 (opens new window)
- Playwright 快速上手指南 (opens new window)
- 使用 Playwright 基于多浏览器进行 javascript 自动化测试的简单教程- Applitools (opens new window)
- 深度解读 - TDD(测试驱动开发) (opens new window)
# 八、求赞、求三连
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿 (opens new window)。
- 01
- 2023/02/08 00:00:00
- 02
- 2023/01/03 00:00:00
- 03
- 2022/12/21 00:00:00