背景
测试是为了保证研发产品交付物质量的重要手段,也是软件生命周期的一部分 研发同学在此周期也是重要的参与者,毕竟 bug 都是同学们写的? 那么研发同学该如何理解测试呢?
测试简介
我们大致可以从两方面对测试分类,测试种类和测试阶段
测试种类
- 功能测试:主要验证功能是否符合需求,是否遗漏
- 性能测试:主要关注系统提供能力,比如后端服务关注的 QPS, TPS,前端关注的 FCP,FMP 等指标
- 健壮性测试:主要关注系统的边界数据情况,非法数据会不会引起系统崩溃等
- 安全测试:主要是验证产品是否符合安全需求定义和产品质量标准的测试
测试阶段
- 单元测试:本阶段主要是研发人员对当前最小可用功能的检查与验证
- 集成测试:单元测试通过后,对由几个子功能组成的子系统的测试
- 回归测试:检查已有功能的正确性检查
- 系统测试:在产品发布前做的最后一轮测试,对整个系统进行测试
测试种类与测试阶段的关系
测试阶段 | 测试类型 | 参与人员 | 单元测试 | 功能测试、健壮性测试 | 研发同学 | 集成测试 | 功能测试、健壮性测试 | 研发同学 | 回归测试 | 功能测试、健壮性测试、安全测试 | 研发&测试同学 | 系统测试 | 功能测试、性能测试、健壮性测试、安全测试 | 测试同学 |
---|
举个栗子
假设我们现在有一部电梯
功能测试:开门、关门、报警电话、轿厢上升、轿厢下降、不同楼层停留、不同楼层呼叫 健壮性测试:同时按上下呼叫按钮、不选楼层,选择全部楼层、载重量测试、停电测试 安全测试:超载报警测试,轿厢门阻塞报警测试 性能测试:1层到最高层空载耗时,1层到最高层满载耗时
市场情况
回归正题,测试在前端领域该怎么做,有哪些工具来帮助我们完成测试 对前端同学来说,前端测试分为两种,UT 和 E2E UT 测试就是我们常说的单元测试,我们围绕着功能 module 以及 function 来编写 test case,组合这些 test case 形成 test suits,来完成我们的单元测试 目前主流测试框架:jest, mocha, jasmine
E2E 测试,是 End-to-End 测试,在此阶段,我们更关注整个操作链路的正确性 目前主流测试框架:playwright, pupeteer, nightwatch, phantomjs, selenium
选型
简便、通用、易学、高可扩展是框架选择的原则 结合市场情况,选择目前市场认可度最高的jest框架 jest 是由 Facebook 出品,集成了 expect, chalk, jsdom, jasmine, sinon 等测试库,同时通过一些插件,可以打通 E2E 测试,实现 UT 与 E2E 的全覆盖测试
jest 简介
jest 是一个驱动框架,负责运行测试用例,展示测试结果。我们是以 module 为单位书写具体的测试用例,每个 module 为一个独立的测试环境,jest 测试套件生命周期有 beforeAll
, beforeEach
, afterAll
, afterEach
基本 api 有 describe
, test
, expect
详细api地址:jestjs.io/zh-Hans/doc…
来个栗子?:
- GitHub:github.com/willchou/ut…
- CodeSandBox:codesandbox.io/s/agitated-…
import {initConfig, login, resetPassword, getChildrenAssetsByAssetId, addAsset} from '../src/utils';
// 此module所有测试用例运行前执行
beforeAll(() => {
initConfig();
})
describe('account test', function () {
describe('#login()', function() {
test('should return true', function () {
return login('test', 'test').then((res) => {
expect(res).toBeTruthy();
});
})
})
// describe可以嵌套
describe('#resetPassword()', function () {
test('should return true', function() {
return resetPassword('test', 'test', 'test1').then((res) => {
expect(res).toBeTruthy();
})
});
// describe中可以包含多个test case
test('should return assets array', function () {
return getChildrenAssetsByAssetId('1').then((res) => {
return expect(res).toEqual([{
assetId: '11',
assetName: '11',
}]);
})
})
})
})
// test case可以脱离describe运行
test('should return true', function () {
return login('test', 'test').then((res) => {
expect(res).toBeTruthy();
});
})
test('should return full resp', function() {
return addAsset('1', '1', {
responseRaw: true,
}).then((res) => {
return expect(res).toMatchObject({
data: {
success: true,
code: 200,
msg: '',
result: true,
},
status: 200,
statusText: 'OK',
})
})
})
- 通过 expect 断言检测结果,参考上例
- 支持异步处理,参考上例
- 通过 Mock 方法,让测试更集中在待测试 function 本身, 参考例子2
- 使用 snapshot,测试 ui 渲染的一致性,参考例子2
- 测试覆盖率报告,jest --coverage
功能代码:
// example 2
// mock function + snapshot
// src/Clock.jsx
import React, {useEffect, useState} from 'react';
const Clock = () => {
const [now, setNow] = useState(Date.now());
useEffect(() => {
const timer = setTimeout(() => {
setNow(Date.now());
}, 1000);
return () => {
clearTimeout(timer);
}
}, [])
return (
<div>
timestamp is {now}
</div>
);
}
export default Clock;
测试代码:
// test/Clock.test.js
import React from 'react';
import render from 'react-test-renderer';
import Clock from '../src/Clock';
jest.useFakeTimers();
Date.now = jest.fn(() => 1615972229101);
beforeEach(() => {
jest.clearAllTimers();
})
test('clock snapshot', () => {
const tree = render.create(<Clock />).toJSON();
expect(tree).toMatchSnapshot();
})
test('setTimeout tests', () => {
const tree = render.create(<Clock />).toJSON();
expect(setTimeout).toHaveBeenCalledTimes(2);
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 1800);
})
测试结果:
接下来,我们更新 Clock.jsx,line 18 文本有更新。这时 snapshot 结果发生变化,我们需要手动更新一下 snapshot 结果,否则测试用例还是会使用老版本的 snapshot 作为参照,导致测试结果不符合预期:
import React, {useEffect, useState} from 'react';
const Clock = () => {
const [now, setNow] = useState(Date.now());
useEffect(() => {
const timer = setTimeout(() => {
setNow(Date.now());
}, 1800);
return () => {
clearTimeout(timer);
}
}, [])
return (
<div>
the timestamp is {now}
</div>
);
}
export default Clock;
没有更新 snapshot 时:
更新 snapshot,并测试:
总结
测试需要投入大量资源开发维护,短期收益并不大,但从长远来看,可以帮忙开发和测试同学节省大量回归测试时间。同时,UT 测试还应该是研发同学自信的来源。UT 测试不一定适应每个项目和团队,短周期一次性项目和团队研发资源不足的场景就不太适合在 UT 测试投入资源。所以,还需结合项目实际情况和团队资源综合评估判断
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!