前端单元测试入门

前端单元测试

一:什么是单元测试
1、概念:

单元测试(unit testing)是指对软件中的最小可测试单元进行检查和验证1。它是一种软件测试方法,用于确保每个独立的软件模块(某个函数或者某个组件)都按照预期运行。

2、单元测试与开发人员有什么关系

其实我们每天都在做单元测试。你写了一个函数,除了极简单的外,总是要执行一下,看看功能是否正常,有时还要想办法输出些数据,如弹出信息窗口什么的,这,也是单元测试,把这种单元测试称为临时单元测试。只进行了临时单元测试的软件,针对代码的测试很不完整,代码覆盖率要超过70%都很困难,未覆盖的代码可能遗留大量的细小的错误,这些错误还会互相影响,当BUG暴露出来的时候难于调试,大幅度提高后期测试和维护成本。

3、单元测试的好处

对于程序员来说,如果养成了对自己写的代码进行单元测试的习惯,不但可以写出高质量的代码,而且还能提高编程水平。

4、怎么单元测试

进行充分的单元测试,应专门编写测试代码,并与产品代码隔离。我认为,比较简单的办法是为产品工程建立对应的测试工程,为每个类建立对应的测试类,为每个函数(很简单的除外)建立测试函数。我们前端选择jest库来写单元测试函数。

二:为什么选择jest库

Jest是Facebook出品的一个测试框架,相对于其他测试框架,它的一大特点就是内置了常用的测试工具,比如自带断言、Mock功能、测试覆盖率工具,实现了开箱即用1。此外,Jest也以其速度快、使用简单和容易配置而受欢迎2

三:从0开始使用jest库
1、安装
npm config list
npm config set registry https://registry.npm.taobao.org //为npm加速

npm install jest -D
or
yarn add --dev jest
2、如何写测试文件

测试文件目录:tests 或者__tests__

测试脚本文件取名:utils.test.js

待测试文件: utils.js

3、jest库的一些简单知识
  1. test方法:Jest封装的测试方法,一般填写两个参数,描述和测试方法

    it是test方法的
    it('测试函数1', () => {
        expect(sum(2, 3)).toBe(5)
      })
    
  2. expect方法 :预期方法,就是你调用了什么方法,传递了什么参数,得到的预期是什么

    expect(sum(2, 3)).toBe(5)
    
  3. describe创建一个测试集。

    这个方法接受两个参数,它的语法和test 的一致,第一个参数也是字符串,对这一组测试进行描述, 第二个参数是一个函数,函数体就是一个个的test 测试。
    
    describe('一组测试函数', () => {
      it('测试函数1', () => {
        expect(sum(2, 3)).toBe(5)
      })
       it('测试函数2', () => {
        expect(sum(2, 3)).toBe(4)
      })
    })
    
  4. 匹配器–断言函数

    全部断言函数

toBe():绝对相等(===)
toEqual():简单类型绝对匹配;复杂类型内容结果的匹配
toBeNull():匹配null
toBeUndefined():匹配undefined
toBeDefined():匹配非undefined
toBeTruthy():匹配转化后为true
toBeFalsy():匹配转化后为false
toBeGreaterThan():相当于大于号
toBeLessThan():相当于小于号
toBeGreaterThanOrEqual():相当于大于等于号
toBeLessThanOrEqual():相当于大于等于号
toBeCloseTo():解决js浮点错误
toMatch(regExp/string):用正则表达式或者字符串匹配字符串片段
toContain():匹配数组或者Set中的某一项
toThrow():匹配异常处理,如果抛出了异常就过测试用例
expect({a:1}).toBe({a:1})//判断两个对象是否相等
expect(1).not.toBe(2)//判断不等
expect(n).toBeNull(); //判断是否为null
expect(n).toBeUndefined(); //判断是否为undefined
expect(n).toBeDefined(); //判断结果与toBeUndefined相反
expect(n).toBeTruthy(); //判断结果为true
expect(n).toBeFalsy(); //判断结果为false
expect(value).toBeGreaterThan(3); //大于3
expect(value).toBeGreaterThanOrEqual(3.5); //大于等于3.5
expect(value).toBeLessThan(5); //小于5
expect(value).toBeLessThanOrEqual(4.5); //小于等于4.5
expect(value).toBeCloseTo(0.3); // 浮点数判断相等
expect('Christoph').toMatch(/stop/); //正则表达式判断
expect(['one','two']).toContain('one'); //匹配数组



test('compiling android goes as expected', () => {
  expect(compileAndroidCode).toThrow();
  expect(compileAndroidCode).toThrow(ConfigError); //判断抛出异常
})
4、运行

将如下代码添加到 package.json 中:

{
  "scripts": {
    "test": "jest"
  }
}

运行环境配置

要解决这个问题,需要用到 Babel 把代码进行转化就OK了,如果想让 Babel 支持 ESM,我们需要三个包:

@babel/core:babel核心库
@babel/preset-env:进行 ES 语法转换的库
babel-jest:和 Jest 通信的库,用来检测是否安装了上面两个依赖

yarn add -D @babel/core @babel/preset-env babel-jest 或者
npm i @babel/core @babel/preset-env babel-jest -D


//.babelrc 配置:主要有两个参数 presets(预设) plugins(插件)
// presets :是某一类 plugin 的集合,包含了某一类插件的所有功能。
// plugin : 将某一种需要转化的代码,转为浏览器可以执行代码。

添加.babelrc文件进行简单的babel配置
{
  "presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]
}

最后,运行 yarn test 或者 npm test ,Jest 将输出如下信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RkKhIr2L-1680525155099)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230329211059138.png)]

5、jest覆盖率配置
最简单
"scripts": {
    "test": "jest --coverage"
  },
  
出测试覆盖率报告
npx jest --coverage
6、 异步测试

基于jest提供的两个方法jest.useFakeTimersjest.runAllTimers可以更优雅的对延时功能的测试。

describe('定时器相关测试', () => {
    // 开启定时函数模拟
    jest.useFakeTimers();

    function foo(callback) {
        console.log('foo...')
        setTimeout(() => {
            callback && callback();
        }, 1000)
    }
    it('断言异步测试', () => {
        //创建mock函数,用于断言函数被执行或是执行次数的判断
        const callback = jest.fn();
        foo(callback);
        expect(callback).not.toBeCalled();
        //快进,使所有定时器回调
        jest.runAllTimers();
        expect(callback).toBeCalled();
    })
});

还可以使用async await

describe('定时器相关测试', () => {
    
    function fetchData(v){
        return new Promise((resolve,reject) => {
            resolve(v)
        })
    }

    test('the data is peanut butter', async () => {
      const data = await fetchData();
      expect(data).toBe('peanut butter');
    });

    test('the fetch fails with an error', async () => {
      expect.assertions(1);
      try {
        await fetchData();
      } catch (e) {
        expect(e).toMatch('error');
      }
    });
    }
7、Dom测试

实现dom渲染测试,以及点击事件等交互功能测试。

describe('Dom测试', () => {
    it('测试按钮是否被渲染 ', () => {
        document.body.innerHTML = `
    <div>
        <button id='btn'>小按钮</button>
    </div> `
        console.log(document.getElementById('btn'), document.getElementById('btn').toString())
        expect(document.getElementById('btn')).not.toBeNull();
        expect(document.getElementById('btn').toString()).toBe("[object HTMLButtonElement]");
    });

    it('测试点击事件', () => {
        const onclick = jest.fn();
        document.body.innerHTML = `
        <div>
            <button id='btn'>小按钮</button>
        </div> `
        const btn = document.getElementById('btn');
        expect(onclick).not.toBeCalled();
        btn.onclick = onclick;
        btn.click();
        expect(onclick).toBeCalled();
        expect(onclick).toHaveBeenCalledTimes(1);
        btn.click();
        btn.click();
        expect(onclick).toHaveBeenCalledTimes(3);
    });
});
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值