• 前端测试


    测试

    为什么项目需要测试

    测试是完善的研发体系中不可或缺的一环,前端同样需要测试。一个项目最终会经过快速迭代走向以维护为主的状态,在合理的时机以合适的方式引入自动化能够让我们提前发现 bug,此时定位和修复的速度比开发完再被叫去修改 bug 要快许多;在项目重构或者开发人员发生变化也能保障预期功能的实现。

    可测试方向

    • 界面回归测试: 测试界面是否正常,这是前端测试最基础的环节
    • 功能测试: 测试功能操作是否正常,由于涉及交互,这部分测试比界面测试会更复杂
    • 性能测试: 页面性能越来越受到关注,并且性能需要在开发过程中持续关注,否则很容易随着业务迭代而下降
    • 页面特征检测: 有些动态区域无法通过界面对比进行测试、也没有功能上的异常,但可能不符合需求。例如性能测试中移动端大图素材检测就是一种特征检测,另外常见的还有页面区块静态资源是否符合预期等等。

    前端测试框架

    前端测试工具也和前端的框架一样纷繁复杂,其中常见的测试工具,大致可分为测试框架、断言库、测试覆盖率工具等几类。常见的测试框架有JasmineMocha, 以及要介绍的 Jest

    测试框架的作用是提供一些方便的语法来描述测试用例,以及对用例进行分组。
    测试框架可分为两种,TDD (测试驱动开发)和 BDD (行为驱动开发)。

    前端是一种特殊的GUI软件.

    断言库

    所谓断言,即提供语义化的方法,用于对参与测试的值做各种各样的判断,如不一致就抛出错误。常见的断言库有 should.jsChai.js

    所有的测试用例(it块)都应该含有一句或多句的断言。它是编写测试用例的关键

    1
    expect(add(1, 1)).to.be.equal(2);

    Jest

    Jest 内置了常用的测试工具,如断言、测试覆盖率。

    命名惯例

    测试文件有如下常见的命名惯例。

    • __tests__ 目录下以 .js 为后缀的文件。
    • 以 .test.js(x) 或者 .spec.js(x) 为后缀的文件。

    测试文件可以位于项目根目录下任何位置,可以通过 testMatch 修改默认配置。

    编写测试

    Jest 的作用是运行测试脚本。通常,测试脚本与所要测试的源码脚本同名,但是后缀名为 .test.js。测试脚本可以独立运行。

    测试脚本里包含一个或多个 describe 块, 每个 describe 里应该包含一个或多个 test 块。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* add.js */
    function add(x, y) {
    return x + y;
    }
     
    /* add.test.js */
    const add = require('./add.js');
    describe('加法函数的测试', function() {
    it('1 加 1 应该等于 2', function() {
    expect(add(1, 1)).toBe(2);
    });
    });

    Jest 提供了内置的全局函数 expect 进行断言。

    describe 称为测试套件(test suite),表示一组相关的测试。第一个参数是测试套件的名称,第二个参数是实际执行的函数。

    test 称为测试用例(test case),表示一个单独的测试,是测试的最小单位。第一个参数是测试用例的名称,第二个参数是实际执行的函数。

    1
    2
    3
    it('work without done', () => {}); // 同步执行
     
    it('work with done', (done) => {}); // 触发异步,执行 done() 通知 Jest 之行完毕

    异步测试

    使用单个参数调用 done, Jest 会等 done 回调函数执行结束后,结束测试。如果 done() 永远不被调用,这个测试将失败。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    it('works with done', (done) => {
    var x = true;
    var f = function() {
    x = false;
    expect(x).toBeFalsy();
    done(); // 通知 Jest 测试结束
    };
    setTimeout(f, 4000);
    });

    Jest 支持使用 Promise, 从测试返回一个 Promise, Jest 会等待这一 Promise resolve。 如果 Promise 被拒绝,则测试将自动失败。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    const requestFn = (name) => {
    return new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('name');
    }, 1000);
    })
    }
     
    it('works with promises', () => {
    expect.assertions(1); // 当前测试中执行断言的次数
    return requestFn('mxl').then(data => expect(data).toBe('name'));
    });

    Jest 也支持 async/await 语法的测试,无需多余的操作,只要在 await 后进行断言即可。

    可以使用 expect.assertions 来验证一定数量的断言被调用,以判断异步代码是否如预期一般执行。

    测试组件

    冒烟测试 验证一个组件渲染没有抛出异常,浅渲染并且测试一些输出,完整渲染测试组件的生命周期和状态的改变。

    1
    2
    3
    4
    5
    6
    7
    8
    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
     
    it('renders without crashing', () => {
    const div = document.createElement('div');
    ReactDOM.render(<App />, div);
    });

    初始化测试环境

    使用 browser API 需要 mock,或者在测试前运行全局的配置,可以在 setup.js 文件里配置。

    测试用例钩子

    有时我们想在测试开始之前进行下环境的检查、或者在测试结束之后作一些清理操作,这就需要对用例进行预处理或后处理。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    describe('hooks', function() {
     
    beforeAll(function() {
    // 在本区块的所有测试用例之前执行
    });
     
    afterAll(function() {
    // 在本区块的所有测试用例之后执行
    });
     
    beforeEach(function() {
    // 在本区块的每个测试用例之前执行
    });
     
    afterEach(function() {
    // 在本区块的每个测试用例之后执行
    });
     
    // test cases
    });

    测试用例管理

    项目中测试用例很多,但希望只运行其中的几个,可以用only方法,describe 块和 test 块都允许调用 only方法,表示只运行某个测试套件或测试用例。

    1
    2
    it.only('1 加 1 应该等于 2', () => { ... });
    fit('1 加 1 应该等于 2', () => { ... });

    此外,还有 skip 方法,表示跳过指定的测试套件或测试用例。

    1
    2
    it.skip('1 加 1 应该等于 2', () => { ... });
    xit('1 加 1 应该等于 2', () => { ... });

    覆盖率报告

    Jest 匹配文件生成测试报告,不需要额外的配置。

    除了会再终端展示测试覆盖率情况,还会在项目下生产一个 coverage 目录。

    1
    npm test -- --coverage

    小结

    对于一些需求频繁变更、复用性较低的内容,编写测试用例得不偿失,适合引入测试用例的场景如下:

    • 需要长期维护的项目。它们需要测试来保障代码可维护性、功能的稳定性
    • 较为稳定的项目、或项目中较为稳定的部分。给它们写测试用例,维护成本低
    • 被多次复用的部分,比如一些通用组件和库函数。因为多处复用,更要保障质量

    参考文献

    react-test-demo(git上挺好的中文讲解)
    jest(中文)
    jest(英文)
    Jest Snapshots and Beyond - React Conf 2017
    The Difference Between TDD and BDD

  • 相关阅读:
    SQLServer 使用ADSI执行分布式查询ActiveDorectory对象
    GridView的DataFormatString
    我的第一篇博客
    delphi for php 帮助文档的笔记(二)
    用delphiforphp来编写算法注册机第一节
    delphiforphp的中文环境的搭建
    初步拟定的delphiforphp的学习计划
    取當前日期各种數据庫的寫法(转存,备查)
    php两页间传变量(转发,备查)
    关于delphiforphp我想说的。
  • 原文地址:https://www.cnblogs.com/lixuekui/p/8663736.html
Copyright © 2020-2023  润新知