前端测试介绍及Jest 基本应用

更新日期: 2023-10-20阅读: 798标签: 测试

在开发的时候,总是有各种理由不写测试,像是开发时间太赶、写测试太耗时间、写测试好无聊等等,很多人觉得没写测试照样能开发能上线,但真的是这样吗?本篇就来好好介绍前端测试的大小事。

 

为什么要写测试?

要做什么事情,总是要有个说服人的原因,所以我列了几点写测试的优点:

  1. 确保程式码正确,防止无预期的错误:像是改了A 功能坏B 功能。

  2. 方便重构程式码:测试能确保重构后的功能依然是正确的。

  3. 交接容易:新人进入专案,能快速了解功能,且较不容易改坏原本的功能。

听起来好处很多,那写测试跟一般的人工测试有什么不同呢?

以测试来说总共有分成三个种类:

  1. 单元测试( Unit Text ):针对程式中的最小单元进行测试,例如:Function、Class。

  2. 整合测试( Integration Test ):针对多个组件或模组之间的互动和整合测试,例如:使用者点击按钮跳出弹跳视窗。

  3. 端对端测试( End-to-End Test ):模拟真实使用者敬,测试整个应用程式的功能和流程,例如:使用者登入、使用者注册。

大部分的人工测试都会归类在端对端测试,单元测试及整合测试都会是在开发阶段所进行。

而这三个种类又发展出一个测试金字塔的概念:


  • 越靠近金字塔顶端(E2E 测试),所花费的成本越高,但是越贴近使用者

  • 越靠近金字塔底部(单元测试),所花费的成本越低,但是越贴近开发者

可以看到,进行越多的端对端测试,就会需要花更多的时间以及人力成本,像是写测试报告以及人工测试,但是却是最符合实际使用者的操作流程。所以大部分的专案都会尽量多做端对端测试,以确保使用者体验。

但这也代表,如果今天有程式码写错,可能只是很简单的逻辑错误,但却会导致花更大量的时间在反覆进行端对端测试。所以如果今天能够做好单元测试及整合测试,就能防止花更多的时间在进行E2E 测试。

 

JavaScript 测试框架

讲了那么多写测试的好处,这就来介绍有哪些前端的JavaScript 测试框架:

  1. Jest:由FaceBook 所开发,在react 专案上使用的人较多。

  2. Mocha:主要是Node.js 的测试框架。

  3. Karmaangular cli 预设搭配Jasmine 作为测试框架。

  4. Vitest:近年来兴起的测试框架,同Vite 主打速度快。

这边列了比较常见且较多人使用的测试框架,来做个详细的比较:


种类JestMochaKarmaVitest
发布时间2014201120122020
开发者FaceBookOpen source谷歌Vite
下载量1234
是否内建断言库❌(需搭配chi)❌(需搭配Jasmin)
是否含模拟函式❌(需搭配Sinon.js)❌(需搭配Sinon.js)
跑测试速度2341
  • 断言:判断数入是否符合预期,Ex: expect(1+1).toBe(2)
  • 模拟函式:模拟元件或函式,Ex: jest.fn()

目前比较主流且最多人用的是Jest,Mocha 及Karma 没有内建基本的断言及模拟函式,且测试速度较慢,而Vitest 测试速度最快,但发展还不成熟,可以持续观望。

 

Jest 特色

  • 内建断言库

  • 内建模拟函式

  • 内建测试覆盖率

  • 内建快照测试 

  • CRA内建,Next.js、Vite也支援

基本语法

假设今天要测试一个加总的函式是否正确:

sum.js

const sum = (a, b) => {
  return a + b;
};
export default sum;

那测试代码就会长这样:

sum.test.js

import sum from './sum.js';

describe("sum function testing", () => {
  it("add 1 + 2 to equal 3", () => {
    expect(sum(1,2)).toBe(3);
  });
});
  • describe : 大范围的测试描述

  • it / test : 详细的测试案例描述

  • expect : 断言

  • toBe : 断言的方法 

在Terminal 输入:

jest sum.test.js

就会去跑有测试标记的档案,并显示测试结果:


除了基本语法外,Jest 还提供四个可以让测试代码更整洁的方法

  1. beforeAll : 在所有测试开始前执行

  2. beforeEach:在每个测试案例开始前执行

  3. afterEach:在每个测试案例结束后执行

  4. afterAll:在所有测试结束后执行

模拟函式

在测试中,需要把测试项目尽量单一化,所以会尽量把一些外部的引入的函式或模组进行模拟,比较常见的就是模拟发api 回传:

fetchData.js

import axios from 'axios';
import url from './url.js';

const fetchData = async() => {
  const response = await axios.get(url);
  return 'My content is:' + response.data;
}
export default fetchData

当我们要测试fetchData这个函式时,就需要去模拟axios 回传,只测试函式本身的功能,所以测试程式码会是这样:

fetchData.test.js

import fetchData from './fetchData.js'
import axios from 'axios';

jest.mock('axios'); //Mock axios

describe('test fetchData function',() => {
  it('call fetchData with "Hello" text get "My content is:Hello", () => {
    axios.get.mockResolvedValue({ data: 'Hello' }); // Mock response
    const res = fetchData();
    expect(res).toEqual('My data is:Hello)
  };
});

这边需要先使用jest.mock去模拟axios 套件,再使用mockResolvedValue去模拟axios.get函式回传的response,这样就可以很单纯的测试这个函式回传是否正确,而不用实际的发API 请求。

测试覆盖率

Jest 有提供一个测试覆盖率的功能,可以显示有哪些程式码有被测试到,只要下指令

jest --coverage

就可以在Terminal 显示测试覆盖率


不过这样看起来很不好看,所以Jest 会同时建立一个coverage 的资料夹,里面会有一个html 档案,打开就会显示转换后的图表


它总共有四个指标

  1. Statements : 有多少比例语句被执行到,一个 console.log(); 就算是一个语句,一行中可以有多个Statements。

  2. Branches:条件语句,像是if ... else 或是switch,每个情况都是一个Branch。

  3. Functions:一个档案有多少比例的函式被执行到。

  4. Lines:有几行的程式码被执行到,基本上Lines 的数量会小于Statements 的数量

并不是需要所有指标都100% 被覆盖,最重要的就是BranchesFunctions,属于会影响功能逻辑的程式码,能尽量提高测试覆盖率是最好的。

快照测试Snapshot Testing

快照就如同字面上的意思,就是快速的拍一张照,只是这一张照片是dom 元素的照片,用意是当UI 有改变时,如果有建立快照,Jest 就可以很快的把当下的DOM跟快照做比较,找出有哪里不一样,这样可以很快地抓到错误。

假设现在有一个函式会根据传入的文字回传一个h1 的标题元素

getTitleHtml.js

const getTitleHtml = (text) => {
  return `<h1>${text}</h1>`;
}
export default getTitleHtml;

Jest 提供toMatchSnapshot()断言方法去比较快照。

getTitleHtml.test.js

import getTitleHtml from './getTitleHtml';
describe('testing snapshot', () => {
  it('match h1 element snapshot', () => {
    expect(getTitleHtml("Hello")).toMatchSnapshot();
  }
} 

跑一次测试会得到下面的结果


在第一次跑测试的时候,会在__snapshots__ 档案建立快照


里面的内容会是长这样

__snapshots__/getTitleHtml.test.js.snap

exports['testing snapshot match h1 element snapshot 1'] = "<h1>Hello</h1>"

它是利用describe跟it的测试描述去记录DOM 的内容。

那再来测一次原本的函式,这次给他不一样的内容:

import getTitleHtml from './getTitleHtml';
describe('testing snapshot', () => {
  it('match h1 element snapshot', () => {
    expect(getTitleHtml("Hello World !")).toMatchSnapshot(); // 更改 DOM 內容
  }
} 

再跑一次测试就会跑出错误,并且显示哪边不一样。


如果想更新快照,只要在watch 模式输入u (update),就会把快照的内容更新成现在的DOM 内容。

 

总结

  1. 在开发时多写单元测试整合测试是可以很有效的减少E2E 的测试成本及时间。

  2. 以主流框架来说,Jest是最多人使用且功能完善的。

  3. 大部分的JavaScript 的测试框架语法都大同小异,所以只要学习某一个框架语法都是可以通用的。

  4. Jest 提供的测试覆盖率可以有效的找出未测试的程式码。

  5.快照测试的用意比较像是提醒开发者UI 有不一样,所以通常会在确认画面内容不会更动的情况下进行测试,不然会导致常常测试不通过。

链接: https://fly63.com/article/detial/12531

测试工具比较:选Jest,不选Mocha

Jest的未来看起来非常令人激动!看到Jest推陈出新如此快速,我感觉它将很快成为整个React生态系统中大部分项目的首选工具。我建议,应该把测试迁移到Jest上去。

你需要了解的前端测试“金字塔”

如果您正在测试前端应用程序,则应该了解前端测试金字塔。在本文中,我们将看到前端测试金字塔是什么,以及如何使用它来创建全面的测试套件。

web网页性能测试工具都有哪些

作为前端开发,我们不仅需要满足产品需求功能的实现,同时也需要对自己做的网站进行安全、易用性、性能等方面的考虑。随着目前技术不断进步,web页面的性能测试工具也在不断完善,通过这些工具,我们可以客观的评价web网站的质量水平。

js单元测试工具-jest自动化测试

jest 是 facebook 开源的,用来进行单元测试的框架,可以测试 javascipt 和 react。jest 提供了非常方便的 API,可以对下面的场景方便的测试:一般函数、异步函数、测试的生命周期、react 测试

web测试要点、方法_web端测试大全总结

web测试大全,测试web网站有哪些点呢?主要包括:功能测试、兼容性测试、安全测试、输入框测试、用户权限测试等

前端性能测试工具整理简介_性能测试工具都有哪些?

前端性能测试工具都有哪些:Favicon、Open Graph、图片优化-压缩图像、CSS 优化-Autoprefixer、Purifycss、minify CSS、减少载入时间、GZIP、CDN、优化平台-Sentry、Google Tag Manager

不用写代码,也能做好接口测试

本文你将了解到:1、接口测试基本概念,包含什么是接口,什么是接口测试,为什么要做接口测试;2、接口测试用例设计,3、怎样不用写代码,也能快速的根据开发的API文档完成接口自动化测试脚本

Selenium打开浏览器加载慢的原因

在自动化元素定位操作中经常使用智能等待来加强定位的强壮性,主要就是因为WebDriver没有提供页面加载场景的方法;在使用JavaScript知识的突然心生灵感,可以使用JavaScript来配合验证页面加载,结果发现我真是井底之蛙。

power assert_更智能、优雅的全方位 assert 断言库

在写测试代码时,以往我们需要翻阅文档,学习各种 API 才能明白如何操作断言。而现在我们可以透过 power-assert 的 assert 方法来减轻调试压力。不仅如此,它还提供更加直观,具体的运行效果,帮助 DEBUG。写测试代码,其实可以很容易。

常用的web网站负载/压力/性能测试工具

在网站上线发布之前,我们除了必要的安全、功能测试外,往往还需要进行压力测试。通过模拟实际应用的软硬件环境及用户使用过程的系统负荷,长时间或超大负荷地运行测试软件。包括:Apache JMeter 、LoadRunner、NeoLoad等

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!