前端单元测试(一) - 入门向

目录

概述

为何要写测试?

从自己的经验来说,在开发阶段,写测试能帮助自己对功能的实现,有一个较为全面的思考,并且降低后续修改引入 Bug 的几率。在交付之前,就能排除大量的 Bug。在后续测试,或需求变更的情况下,修改代码之后,可以保证不对已经稳定的功能引入新 Bug。从别人处接手项目时,也能大大避免因新接手人员对项目不熟悉,引入的新问题。
总体上来说,为自己的代码写测试,是一项首次繁琐、后续便利的工作,并且从长远来看,一个项目后续修改的频率要远远大于首次的构建和开发,不论对测试、开发、交接都是利大于弊的╮(╯_╰)╭。
这篇以本人入手时的体验,简单介绍前端测试的部分内容。

前端测试的类型

有一种关于测试的分类,称为前端测试金字塔,将前端测试从塔底到塔尖分为:

  • 单元测试(Unit Tests)
    顾名思义,对一个功能单元进行测试,如一个对日期进行格式化的方法。
    单元测试是非常细化和相对全面的,要保证一个单元代码的可靠性,需要尽可能地对所有情况编写测试脚本。
  • 快照测试(Snapshot Tests)
    快照测试是对 UI 组件渲染结果的测试。
    在 Jest 中,快照测试并不是对图片进行比对,而是保存渲染组件的标记,使得快照文件体积小,而测试速度快。
    更多关于 Jest snapshot test
  • 端到端测试(End to End Tests)
    是对模拟我们对项目的实际操作,测试过程较为复杂和繁琐,耗时长。

想了解更多关于这几种测试类型的细节,请看 前端测试金字塔

TDD vs BDD

测试驱动开发(TDD)是先写测试,根据测试的内容实现具体的功能代码,再用之前的测试进行验证。TDD 是用测试来推动功能的实现。
行为驱动开发(BDD)是从行为的角度来定义测试的内容,用自然语言描述测试用例。
有关于 TDD 和 BDD 的思考,可以参考 The Difference Between TDD and BDD

常用前端单元测试框架

常见的测试框架有 JestMochaJasmine 等。
这里举例说明一下 Jest 和 Mocha。

Jest

  • 配置简单(开箱即用)
  • 自带断言库(在 Jest 中称为 matchers
  • 内置的覆盖率(coverage)统计
  • 内置的快照功能
    Jest 由 Facebook 团队开发维护,故对于测试 React、ReactNative 项目支持友好。

使用

(来自官网的例子)
新建一个项目(npm init),新建一个 /src 目录和 /test 目录,用于存放功能代码和测试代码。
安装 Jest,无需额外配置:

npm install --save-dev jest
// or
yarn add --dev jest

完成后的目录如下:

/project
    -/node_modules
    -/src
    -/test

在 /src 文件目录下新建一个 sum.js 文件,

function sum(a, b) {
    return a + b;
}
module.exports = sum;

在 /test 中新建一个 sum.test.js 文件,引入 sum.js 的方法:

const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

在 package.json 的 scripts 中新增:

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

之后运行:

npm run test
// or
yarn test

就可以得到结果:

PASS  ./sum.test.js
✓ adds 1 + 2 to equal 3 (5ms)

上面例子中的“expect(sum(1, 2))”称为断言,在 Jest 中叫做“matchers”,Jest 提供了多种 API 满足不同的情况。
Jest 为每个测试文件预置了一些全局方法和对象,“test” 用来包裹一个最小的测试单元,一系列相关的测试单元可以用 “describe”包裹:

const myBeverage = {
  delicious: true,
  sour: false,
};

describe('my beverage', () => {
  test('is delicious', () => {
    expect(myBeverage.delicious).toBeTruthy();
  });

  test('is not sour', () => {
    expect(myBeverage.sour).toBeFalsy();
  });
});

Mocha

  • 配置自由灵活
  • 自行引入需要的断言库
  • 支持几种不同的测试代码的组织形式(包括 BDD、TDD 等)
  • 可运行在 Node 环境和浏览器
    Mocha 的有更高的自由度,更能配合需要高度定制化的项目,插件配置方面也能找到大量的参考信息。

使用

安装方式类似。
Mocha 需要自行引入断言库(即需要自行额外安装对应的库),在使用上,和 Jest 并没有太大区别:

var assert = require('assert')
describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      assert.equal([1,2,3].indexOf(4), -1)
    })
  })
})

可以直接运行:

./node_modules/mocha/bin/mocha

或者也在 package.json 中新增 scripts:

"scripts": {
    "test": "mocha"
}
...
npm test

Mocha 中 describe 是作为 BDD 的一种接口,它同时提供适用 TDD 的接口:suite(), test(), suiteSetup(), suiteTeardown(), setup(), and teardown()等:

suite('Array', function() {
  setup(function() {
    // ...
  });

  suite('#indexOf()', function() {
    test('should return -1 when not present', function() {
      assert.equal(-1, [1,2,3].indexOf(4));
    });
  });
});

除了 BDD、TDD,Mocha 还支持 Exports,QUnit,和 Require-style 接口,具体参考文档

More

前端测试该写些什么

刚开始接触入门前端测试时,最困扰我的就是测试到底该写什么了。
对 UI 进行测试的目的较为明确,只要根据页面需要达到的效果,对照着加入测试即可。但若进行单元测试,或者针对功能进行测试时,我们总是希望覆盖面能广一点、考虑的情况能全面一点,以达到更好的测试效果。不同的项目代码的功能、组织方式大相径庭,很难有一套通用的定论来指明我们的测试代码具体应该怎么写,但一些思考角度是可以分享和借鉴的。
以下是我针对一个功能型(或者说工具型)项目进行测试的几个方面:

  • 明确的功能点
    即需求方给的明确的需求,以及为了实现这些需求,需要达到的一些标准。
  • 输入值、输出值、边缘数据校验(特别是工具类型的单元)
    如输入值不符合标准的情况,输入值不符合标准的情况也可能存在多种情形,都需要分情况考虑。
  • 测试过程中出现 Bug 的情况
    即使在开发过程中通过测试规避了很多问题,但不可避免仍会有一些特定场景会引出 Bug,功能修复后添加针对该场景的测试脚本,可以规避该场景 Bug 的重复出现。

写什么都比没有开始好

对于不同的项目,需要侧重的测试方面也大不相同,真正开始思考如何全面地测试一个项目,并且转换成测试代码之后,能大大提升代码质量,提升代码的复用性、模块化划分、全面性。
从长远上来看也能显著提升大型项目的开发效率,特别是参与开发人员多、交接频繁、迭代频率高的项目。

Thanks.

其他参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 什么是单元测试 单元测试(unit testing)是指对软件中的最小可测试单元进行检查和验证。 简单来说,单元就...
    kyleBoy阅读 1,542评论 0 3
  • 前言 随着Web业务的日益复杂化和多元化,前端开发也有了前端工程化的概念,前端工程化成为目前前端架构中重要的一环,...
    CharmSun阅读 1,215评论 0 1
  • 大多数开发者都知道需要写单元测试,但是不知道每个单元测试应用的主要内容以及如何做单元测试,在介绍jest测试框架前...
    糖小工阅读 6,049评论 0 11
  • 前言 本篇文章是我在学习前端自动化单元测试时的一些思路整理,之前也从未接触过单元测试相关工具,如有错漏,请读者斧正...
    Awey阅读 12,623评论 8 38
  • 今天把两轮卸掉,宝贝儿学骑自行车。 这段时间看到很多同龄小朋友都可以骑两轮自行车,宝贝儿也是羡慕!她也想自己学习两...
    静泽福淼阅读 121评论 0 0