大前端测试

引子

在之前分享的编辑器相关文章里,讲到了语雀是全栈js开发的,并且号称团队没有测试工程师,参考文章里面有放关于全栈 JavaScript 测试的相关总结分享,今天我们就聊一聊前端的测试。

单元测试

  1. 定义:

在计算机编程中,单元测试(Unit Testing)又称为模块测试,是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。
程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。

  1. 意义
  • 提升能力
  • 提升效率:及早发现问题
  • 追求卓越:有助于开发人员去思考代码结构的设计,让代码更加有利于测试
  • 覆盖全面:能够覆盖到QA测试覆盖不到的情况
  • 大型项目,协同开发,公共抽离组件会出现一些问题,有了单测后,更强壮,更易读,升级时,回归测试任务少,提升公共组件的质量。
  1. 测试方法论 TDD&BDD
  • TDD:Test-driven development 测试驱动开发
    TDD 从测试的角度来检验整个项目。大概的流程是先针对每个功能点抽象出接口代码,然后编写单元测试代码,接下来实现接口,运行单元测试代码,循环此过程,直到整个单元测试都通过。
  • BDD:Behavior Driven Development 行为驱动开发
    是通过编写行为和规范来驱动软件开发。更注重功能本身。
  1. 原则:FIRST
  • F fast 快速 过程快
  • I Isolate 隔离 测试用例应当独立执行,避免一个测试结果依赖于另外一个。需要把测试分解成尽可能小的单元,这将帮我们确定在错误发生时的确切代码位置。
  • R Repeatable 可重复:多次运行测试应该产生相同的结果,如果不确定,就不知道哪些结果是有效的,哪些又是无效的。另外,反复性可以确保我们的测试不依赖于外部因素(诸如网络或 CPU 负载)。
  • S Self-validating 自我验证无需人工
  • T Timely 及时,上线前
  1. 测什么
    结果正确
    边界条件检查
    反向关联(加密解密 读写操作)
    强制错误条件

  2. 测试的核心
    断言(assert)即表达程序设计人员对于系统应达到状态的一种预期。

前端测试框架:

帮助我们把测试代码抽离出来,作为一个整体结构化地去设计测试用例,放置到专门测试文件,然后也可以实现自动运行以及显示测试结果。
介绍:
Mocha,Jest,Jasmine 可以说都是测试框架,可以达到之前说的,抽离,结构化,自动运行等等,其中 Jest 是一个相当全面的框架,且零配置,同时需要注意的是 Jest 也是基于 Jasmine 的,所以 Jest 的一些语法和 Jasmine 一模一样,连报错有时都会相同。
Chai,Should 都属于断言库,它们的 API 相对测试框架自带的断言 API 更加语义化,更好用,可以和上面的测试框架结合着用。
Karma 是一个 Test-Runner,可以说是凌驾测试框架之上,可以让给你的浏览器自动跑所有的测试用例。
Enzyme是由airbnb开发的React单元测试工具。它扩展了React的TestUtils并通过支持类似jQuery的find语法可以很方便的对render出来的结果做各种断言。

Jest

https://github.com/facebook/jest star 36.2k
Jest是Facebook开发的一个测试框架,它集成了测试执行器、断言库、spy、mock、snapshot和测试覆盖率报告等功能。React项目本身也是使用Jest进行单测的,因此契合度相当高。

  • 自带断言函数
exspect(运行结果).toBe(期望的结果);
//常见断言方法
expect({a:1}).toBe({a:1})//判断两个对象是否相等
expect(1).not.toBe(2)//判断不等
expect({ a: 1, foo: { b: 2 } }).toEqual({ a: 1, foo: { b: 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'); //包含
  • 支持异步测试
  • 支持Dom测试
  • Mock Functions

一个简单的示例:

  1. 安装 npm install --save-dev jest
  2. 新建测试文件 unit.test.js
import {dealData} from "./src/util/Util";

describe("dealData测试",()=>{
  test('dealData 1 GB to equal 1 GB', () => {
    expect(dealData(1, 'GB')).toEqual({
      value:1,
            unit:'GB'
    });
  });
  //输入数据大于1024GB则转换为TB
  test('dealData 2048 GB to equal 2 TB', () => {
    expect(dealData(2048, 'GB')).toEqual({
      value:2,
            unit:'TB'
    });
  });
  //输入数据大于1024*1024*10GB则转换为PB
  test('dealData 20971520 GB to equal 20 PB', () => {
    expect(dealData(20971520, 'GB')).toEqual({
      value:20,
            unit:'PB'
    });
  });
  //PB为最大单位,不进行进一步处理
  test('dealData 419430400 GB to equal 20 PB', () => {
    expect(dealData(41943040000, 'GB')).toEqual({
      value:40000,
            unit:'PB'
    });
  });
  //其他单位不进行转换
  test('dealData 1 KB to equal 1 KB', () => {
    expect(dealData(1, 'KB')).toEqual({
      value:1,
            unit:'KB'
    });
  });
  //接口异常时数据不进行转换
  test('dealData --  to equal --', () => {
    expect(dealData('--', '')).toEqual({
      value:'--',
            unit:''
    });
  });
})

注:dealData 是一个抽离出来的工具函数,帮助动态处理业务数据单位

  1. package.json中增加代码
{
  "scripts": {
    "test": "jest"
  }
}
  1. 运行npm run test
    image.png

Enzyme

https://github.com/enzymejs/enzyme star 19.7k
React测试必须使用官方的测试工具库,但是它用起来不够方便,所以有人做了封装,推出了一些第三方库,其中Airbnb公司的Enzyme最容易上手。

项目实战时,结合jest和enzyme。

Enzyme为我们提供来三种渲染组件的方法shallow、render、mount。
shallow 方法就是官方的shallow rendering的封装。
render 方法将React组件渲染成静态的HTML字符串,然后分析这段HTML代码的结构,返回一个对象。它跟shallow方法非常像,主要的不同是采用了第三方HTML解析库Cheerio,它返回的是一个Cheerio实例对象。
mount方法用于将React组件加载为真实DOM节点。

测试登录交互例子:

import Login from 'pages/Login';
import React from 'react';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { mount } from 'enzyme';
configure({ adapter: new Adapter() });

const wrapper = mount();
describe('', () => {
 it('标题显示', () => {
   const title = wrapper.find('.title').text();
   expect(title).toBe('登录');
 })
 const accountInput = wrapper.find('.account').find('input');
 const accountTitle = wrapper.find('.account .name').find('span');
 it('输入不合法账号', () => {
     const event = {
         target: {
           value: 'abc123'
       }
     }
   accountInput.simulate('change', event);
   expect(accountTitle.text()).toBe('账户输入错误,请重新输入');
 })
})

uirecorder

https://github.com/alibaba/uirecorder star 1.8k
UI Recorder 是一款面向多端的 UI 自动化录制工具,类似于Selenium IDE 但比Selenium IDE 更加强大!
UI Recorder 非常简单易用,零成本解决测试回归问题。

功能:

  1. 支持所有用户行为: 键盘事件, 鼠标事件, alert, 文件上传, 拖放, svg, shadow dom
  2. 全平台支持,移动端 Android, iOS 录制, 基于 Macaca 实现
  3. 无干扰录制: 和正常测试无任何区别,无需任何交互
  4. 录制用例存储在本地
  5. 支持丰富的断言类型: val,text,displayed,enabled,selected,attr,css,url,title,cookie,localStorage,sessionStorage
  6. 支持图片对比
  7. 支持强大的变量字符串
  8. 支持公共测试用例: 允许用例中动态调用另外一个
  9. 支持并发测试
  10. 支持多国语言: 英文, 简体中文, 繁体中文
  11. 支持单步截图
  12. 支持HTML报告和JUnit报告
  13. 全系统支持: Windows, Mac, Linux
  14. 基于Nodejs的测试用例: jWebDriver

官方教程:https://www.yuque.com/artist/uirecorder/yd7ztf

  • 初始化工程
  • 开始录制,进行界面操作,可以添加断言,悬停等等
  • 结束录制,自动生成脚本文件
  • 利用已有脚本文件进行回归测试

你可能感兴趣的:(大前端测试)