zoukankan      html  css  js  c++  java
  • 前端测试

    测试

    为什么项目需要测试

    测试是完善的研发体系中不可或缺的一环,前端同样需要测试。一个项目最终会经过快速迭代走向以维护为主的状态,在合理的时机以合适的方式引入自动化能够让我们提前发现 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

  • 相关阅读:
    Ext JS学习第三天 我们所熟悉的javascript(二)
    Ext JS学习第二天 我们所熟悉的javascript(一)
    Ext JS学习第十七天 事件机制event(二)
    Ext JS学习第十六天 事件机制event(一)
    Ext JS学习第十五天 Ext基础之 Ext.DomQuery
    Ext JS学习第十四天 Ext基础之 Ext.DomHelper
    Ext JS学习第十三天 Ext基础之 Ext.Element
    Ext JS学习第十天 Ext基础之 扩展原生的javascript对象(二)
    针对错误 “服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF” 的原因分析
    C# 使用HttpWebRequest通过PHP接口 上传文件
  • 原文地址:https://www.cnblogs.com/lixuekui/p/8663736.html
Copyright © 2011-2022 走看看