1.什么是单元测试
单元测试是对软件中的最小可测试单元进行测试。(最小可测试单元是要有结果产出的。例如某个方法,单独的某个操作)
单元测试其实是伴随着敏捷开发,它是对更快开发的一种追求。早发现错误比晚发现错误会更好,保证自己的代码符合要求。
单元测试优点:
- 分模块开发,更容易定位到哪个单元出了问题;
- 保证了代码质量;
- 驱动开发;
具体流程:
- 立项--原型图--分析功能需求--单个功能--写单元测试--开始写代码--跑单元测试--提交代码
单元测试是测试驱动开发:
- 分析需求,根据需求设计功能;
- 根据功能设计单元测试,先编写单元测试;
- 编写代码;
- 保证代码通过单元测试;
测试用例
- 为了某个特殊目标而编织的一系列测试输入,执行,以及输出结果,来测试是否满足需求。
测试套件
- 一组单元测试组合成测试套件(例如:弹窗组件)
2.单元测试有哪些常用库?
测试框架:运行单元测试。
- Jest - 开箱即用,简单轻松(断言库,mock库-Chai,test runner,覆盖率工具都配置好了 )
- Mocha - 需要自己配置
断言库:检测方法是否符合预期。
- Chai - 支持所有风格
- Assert - node环境直接使用
mock库:当有外部依赖/数据 时,通过mock库来进行屏蔽。
- sinon - 单元测试用到的mock库。 注意:mock.js是开发端,进行mock接口的。
test runner:模拟单元测试浏览环境。
- karma
覆盖率工具:产生覆盖率报告。
- istanbul
用覆盖率工具产生的覆盖率有3种:
- 行覆盖率:可执行语句执行比例。
- 函数覆盖率:函数被调用的比例。
- 分支覆盖率:判断语句分支被执行的比例。(if-else分支)
3.基本的使用
安装jest
npm install jest
业务代码:
function add (a, b){ return a + b; }
测试用例--用it开启一个测试用例
it("单元测试描述:", () => { expect(add(1,2)).toEqual(3); })
异步操作,使用回调
function c(a, b, cb){ setTimeout(()=>{ cb(a+b); },1000) }
异步测试用例--回调
it("异步回调测试用例", (done) =>{ function callback(result){ expect(result).toEqual(3); done(); } c(1, 2, callback) })
异步操作,使用Promise
function c(a, b, cb){ return new Promise( setTimeout(()=>{ cb(a+b); },1000) ) }
异步测试用例--Promise
it("异步Promise测试用例", (done) =>{ c(1, 2).then(() => { expect(result).toEqual(3); }) })
外部依赖
const mode =require("./mode.js"); //mode.js module.exports = { f1: function(){ return 3 } }
d方法
function d(){ var res = mode.f1(); return ++res; }
测试d方法,把f1方法屏蔽掉
jest.mock("./mode");
测试用例--外部依赖
it("外部依赖测试用例",() => { var f1mock = mode.f1.mockReturnValue(2); expect(d()).toEqual(3); })
4.在vue中基本的使用
vue-cli,不需要自己去配单元测试,初始化项目时,可选择添加单元测试。
基本步骤:
创建被测试对象(HelloWorld.vue)---》创建test文件(HelloWorld.spec.js)---〉执行npm test
测试套件:一大堆单元测试组合到一起,组合成测试套件。针对某一个组件的测试,都算一个测试套件。
例子:
HelloWorld.vue
mounted: function(){ axios.get('/api').then((data)=>{ this.data = data; }) }
HelloWorld.spec.js
describe('test HelloWorld', ()=>{ it("render data", () =>{ jest.mock("axios"); jest.spyOn(axios,"get").mockResolvedValue({ data:[ {content: "this is 1"}, {content: "this is 2"} ] }); setTimeout(()=>{ const wrapper = mount(HelloWorld); expect(wrapper.html()).toContain("this is 1"); expect(wrapper.html()).toContain("this is 2") }) }) });