前端自动化测试
扫描二维码关注博主公众号,搜索即可免费读。
每日好文伴你地铁时光。
背景:
前端测试是前端工程中很重要的一部分,但是对于大多数开发而言这应该是个名词。因为没用到,据不知名数据统计,不会做自动化测试的开发占据一半之多!
因为前端自动化测试要写测试脚本,大多数中小型公司由于开发周期短,项目也不长期维护,工程管理的不规范,所以就只是打印调试,用户测试,左点点右点点,各个机型各浏览器看一看,没啥问题就OK了。对于小项目而言它的时间成本及可靠度还是人力测试靠谱一点。
所以这部分知识也愈来愈不那么重要了,但是作为前端分支的一部分。以及自己技术广度的拓展,对一些基本概念及某一工具还是要有个认知的。
场景:
以下场景建立自动化测试机制尤为重要,优势明显。
- 项目没固定人员维护,不知道经过多少人手了,改了一个地方线上崩了。这种修改某个模块功能时,其它模块也受影响,很难快速定位bug。
- 多人开发一个项目,一人管一块,代码越来越难以维护。接手某人代码或公共功能的管理。
- 不方便迭代,代码无法重构
- 开发团队中有较初级的开发者,代码质量差,无保障。
- 开发调试某功能后经常注释一行打开另一行,最后注释遗忘。污染源代码
优势:
- 保障项目的可靠性
- 强迫开发者编写易于测试的代码,提高代码质量
- 测试用例有文档的作用,方便维护
- 节省测试资源
- 可享受生产测试报告等集成的功能
劣势:
- 开发成本高、周期长
- 对于简单的小项目、简单的功能需求未必比用户测试精准
相关概念:
- 单元测试:unit [ˈjuːnɪt] ,单元测试是指对程序中最小可测试单元进行的测试,前端泛指对一个函数,一个代码块,一个组件的测试
- 集成测试:integration [ˌɪntɪˈɡreɪʃn] ,前端泛指将单元代码组合成的一个功能测试,代码集合的测试。集成测试也包括UI测试,UI测试用于确保页面正常渲染
- 端到端测试:e2e,打开应用程序模拟输入,检查功能以及界面是否正确。前端泛指人肉去点点输输去测试。这个学名对于前端来说与一些常说的模拟用户测试,冒烟测试差不多一个意思。冒烟测试的意思大概源于计算机的硬件,比如各个零件搭好了,我换某一个零件,换上去通电没有冒烟就证明通过了。如前端一个页面由十块代码组成,你修改了一处,测试整个页面是否完好。
- 断言:比如在写测试用例时,经常需要检查值是否符合某些条件,不符合我们通常会抛出throw error,那程序就断了,无法继续,这种就测试失败了。单元测试中一般必须使用断言,它可以直接定位到报错位置。
- 白盒测试:是基于代码本身的测试,一般指对代码逻辑结构的测试。
- 黑盒测试:一般也被称为功能测试,黑盒测试要求测试人员将程序看作一个整体,不考虑其内部结构和特性,只是按照期望验证程序是否能正常工作
- 沙盒测试:沙盒是在受限的安全环境中运行应用程序的一种做法,这种做法是要限制授予应用程序的代码访问权限。前端泛指通信协议的限制居多,协议族就几种,如HTTP等,你要在人家规定的协议下通信,这种就属于沙盒。沙盒环境又称测试环境和开发环境,是提供给开发者开发和测试用的环境。在该环境中应用功能没有任何限制,但是测试将会受限,在新开发的网站未上线时,我们通常修改电脑中的host文件来访问某一域名。
- TDD:测试驱动开发(Test - Driven - Development),开发某一功能代码之前,先编写单元测试用例代码。(一般都是单元测试,白盒测试)
- BDD:行为驱动开发(Behavior - Driven - Development),大家讨论定需求开发业务代码,然后开发根据用户行为负责编写对应的测试代码(一般都是集成测试,黑盒测试)
UI测试:
一般常用两种方式
像素对比:开发截个页面的截图(参照图),测试脚本执行截图代码(对比图),两图像素自动进行对比,如果每个像素都一样,那么测试通过
快照:这里的快照不是截图,是将页面渲染后的DOM结构生成一个序列化的文本(参照文本),下次再次生成一个序列化的DOM文本(对比文本)。如果内容完全一样,那么测试通过。做快照测试,必须保证多次测试输出快照总是一致的,然而在react中model经常变化,这时就要用mock模拟函数返回固定数据确保model不变
常见工具:
单元测试:Jest、mocha、jasmine、Karma……
集成测试:casperJS、PhantomJS……
端对端测试:Puppeteer、Nightmare、Selenium、Appium、Protractor、Zombie.js、Cypress……
断言库:chai、should……
单元测试推荐Jest,集成测试推荐Puppeteer
像mocha这种没有IDE集成,一般常要配合chai等库一起使用
Jest:Jest 是Facebook推出的一款测试工具
优点:
- 性能、功能、易用性
- 速度快 + 监控模式:比如写了A\B两个自动化测试脚本,会都进行测试,如果改了A,下次就只会测A
- API简单: 少,支持中文
- 易配置:Jest的配置文件简单配置一下就可用
- 隔离性好:代码隔离执行,更精准
- 快照:针对一些不重要的测试用例可以快速略过
- 多项目并行:react/vue 等可与 node 同时进行测试
- 覆盖率:一行命令生成代码报告
- Mock:丰富
- 兼容性:BABEL、TS、Node、React、Vue、Angular
提供了很多API都很方便,如模拟请求,如模拟定时器:
- jest.useFakeTimers() 声明在当前测试文件中使用模拟定时器,声明后,可以直接用expect(setTimeout).toHaveBeenCalledTimes(1)判断定时器调用的次数
- jest.runAllTimers() 立即执行所有定时器
- jest.runOnlyPendingTimers() 立即执行挂起的定时器
- jest.advanceTimersByTime(msToRun) 提前msToTun毫秒执行定时器
Jest expect实现原理
// 测试函数加
function add(a, b) {
return a+b
}
// 测试函数减
function minus(a, b) {
return a-b
}
// 测试函数
function expect(res) {
return {
toBe: function(actual) {
if(res !== actual) {
throw new Error("预期值不符")
}
}
}
}
// 断言处理
function test(s, fn) {
try {
fn()
console.log(`${s}通过测试`)
} catch (err) {
console.error(`${s}没有通过测试`, err)
}
}
// 测试加模块
test('加法1+1', ()=>{
expect(add(1,1)).toBe(10)
})
// 测试减模块
test('加法2-1', ()=>{
expect(minus(2,1)).toBe(10)
})
Puppeteer: Puppeteer是chrome推出的一款浏览器自动化工具,它只能进行浏览器的自动化,本身并不具有测试功能(断言,生成测试报告等)
优点:
- 生成页面屏幕截图或pdf
- 自动提交表单,做UI测试、模拟键盘输入、鼠标操作等
- 创建一个最新的自动化测试环境,用最新的JavaScript和浏览器功能,直接在最新的chrome中做测试
- 捕获你网站的时间线跟踪,以帮助诊断性能问题