前端测试方法

article/2025/10/9 4:17:19

最近在学校的《系统分析与设计》一课的大作业上,由于我担任的是测试工程师的角色,因此小小的研究了一些前端和后端的测试到底要怎么做。本文着重于前端测试方法。

1. 什么是测试?

我把测试定义成:是一段检测你的应用代码(也叫“生产代码”)是否按预期执行的代码。有些人称之为 TDD(Test-Driven Development 或者 Test-Driven Design),但是 TDD 是一种特定的测试方法,它先写测试,然后用测试来驱动产品的设计和实现。

2. 为什么测试?

或者说为什么要将测试以编码形式保留下来(并且一般做模块管理),来做自动化测试。因为我觉得测试肯定是需要的,这个不用解释吧。。。不然如何保证程序没bug?不能保证无bug就不能叫出去了吧。。。

我觉得是因为在项目中代码变动太多,由于使用敏捷开发的方式(事实上就算是瀑布那种,我估计也要)原先的代码和功能经常会有变动。我们要保证每次变动后不会产生新的或旧的bug。那么比起每次都重新测试(以某种非自动化方法进行),显然一个很好的办法就是将测试过程编码,那么每次重新测试只要运行测试代码(换言之,自动化)就可以了。

3. 测试的类型

测试包括单元测试、验收测试、集成测试、端到端测试、组件测试和服务测试等多种。

我认为叫什么名字都不重要,因为各种测试的定义都不难理解。所有的测试都分布于“测试光谱”中,光谱的一头是单元测试,另一头是端到端测试。

测试光谱

光谱的一端——单元测试

顾名思义,代码以单元为单位进行测试。那么什么是单元呢?这就不同的编程语言的定义不一样了。它可以是一个函数、一个模块、一个包或者一个类,甚至是一个对象(比如 JavaScript 和 Scala 语言)。在 JavaScript 中,通常是以类或者模块作为一个单元。

以单元进行测试很重要的一点是其测试是独立的。对于一些场景这种测试非常适合,比如算法、某些功能性函数(如字符串中有多少字符)和包含一组验证性功能的类等场景。

这些场景下进行独立的单元测试非常容易,因为他们不依赖于其他单元。但是假设一个单元依赖于其他单元怎么办?可以有两种做法:两个单元一起测试,或者 mock 另一个单元。

什么是 mock?下面我们举例来解释:

假设一个模块是一个单元,模块中包含了 writeSumToFile 这个函数,函数接收两个数字参数,并把他们的和写入文件中。

这里注意,这个模块自己并没有做写文件操作。写文件操作是在另一个单元 fileSumWriter 中做的。

那么为了测试第一个单元,我们既可以传一个真实的 fileSumWriter 进来,也可以模拟(mock)一个写文件操作(并不用真的实现写操作)。

如果我们传递一个 mock 到这个函数,那么这个单元测试,当然可以叫做“单元测试”,因为没有涉及到其他单元。

光谱的另一端——端到端测试

上面介绍了以一个单元为单位的测试。现在介绍端到端测试——测试整个应用。测试过程中,应用的所有配置会设置成和生产环境一样,应用中的一切都会被测试到。

这两个是“测试光谱”的两端。上面提到的其他测试方法,都是分布在这两个极端中间。他们的基本思路是逐步扩大测试范围,被测试的代码越来越多,mock 的代码越来越少。

4. 单元测试

其实对于单元测试来讲,难的并不是单元测试本身,而是分离代码的艺术,把代码尽量分离成单元可测的模块。单元可测的代码一般都是不依赖于其他模块、不依赖于 I/O 的代码。这是比较困难的,大多数人都倾向于把逻辑代码、I/O 代码和 UI 代码写到一起。困难是困难,但不是说做不到,有很多技巧可以使用,比如你的代码中有一些验证字段,那么你就可以把验证代码组织到一起形成函数,再对这个验证函数进行测试。

用 Mocha 进行单元测试

所有的测试框架都类似,写测试代码调用被测函数,通过测试框架运行他们,其中运行它们的代码通常叫做“runner”。使用mocha进行测试,测试成功的结果大概会是这样子:

使用mocha和nodejs进行前端测试虽然听起来有点怪,毕竟我们的前端代码最终是跑在浏览器的。但是nodejs和前端的逻辑代码其实都是javascript写的,这也是我们项目中使用nodejs的一个好处。

如果实在不放心,或者项目中不使用nodejs的话,我们们还可以使用另一个测试框架,Karma 。使用它可以在浏览器中运行 Mocha 代码,但是这里表达一下我的浅见:单元测试能在 Node 下运行就在 Node 下运行,因为很容易执行和 debug(当然现在在浏览器中执行也很方便)。并且如果代码不需要转译的话,执行的也非常快。

但是我们的代码没有在浏览器中测试确实是个问题,因为我们并不真正地知道代码在浏览器中运行会是什么样子。浏览器中的 JS 执行环境和 NodeJS 环境可能会有微妙的差别。

5. 端到端测试

我们将使用端到端测试整个应用。

是否需要像单元测试那样,测试各种组合呢?并不是,我们已经在单元测试中测试过了,端到端测试不是检查某个单元是否 ok,而是把它们放到一起,检查还是否能够正确运行。

这里推荐selenium-webdriver,这个包能够将打开浏览器,访问url,与dom进行操作等自动化。因此可以想象我们的端到端测试不再需要人工的在浏览器上点点点,而是可以通过编码做到自动化!!

代码实例如下:

const {prepareDriver, cleanupDriver
} = require('../utils/browser-automation')//...
describe('calculator app', function () {let driver...before(async() = > {driver = await prepareDriver()})after(() = > cleanupDriver(driver))it('should work', asyncfunction () {await driver.get('http://localhost:8080')//...})
})

before 中,准备好驱动,在 after 中把它清理掉。准备好驱动后,会自动运行浏览器(Chrome,稍后会看到),清理掉以后会关闭浏览器。

const webdriver = require('selenium-webdriver')
const chromeDriver = require('chromedriver')
const path = require('path')const chromeDriverPathAddition = `: $ {path.dirname(chromeDriver.path)
}`exports.prepareDriver = async() = > {process.on('beforeExit', () = > this.browser && this.browser.quit())process.env.PATH += chromeDriverPathAdditionreturn await new webdriver.Builder().disableEnvironmentOverrides().forBrowser('chrome').setLoggingPrefs({browser: 'ALL',driver: 'ALL'}).build()
}exports.cleanupDriver = async(driver) = > {if (driver) {driver.quit()}process.env.PATH = process.env.PATH.replace(chromeDriverPathAddition, '')
}

前两行引入了 webdriver 和我们使用的浏览器驱动 chromedriver。Selenium Webdriver 的工作原理是通过 API(第一行中引入的 selenium-webdriver)调用浏览器,这依赖于被调浏览器的驱动。本例中被调浏览器驱动是 chromedriver,在第二行引入。

chrome driver 不需要在机器上装了 Chrome,实际上在你运行 npm install 的时候,已经装了它自带的可执行 Chrome 程序。接下来 chromedriver 的目录名需要添加进环境变量中,见代码中的第 9 行,在清理的时候再把它删掉,见代码中第 22 行。

设置了浏览器驱动以后,我们来设置 web driver,见代码的 11 – 15 行。因为 build 函数是异步的,所以它也使用 await。到现在为止,驱动部分就已经设置完毕了。

接下来这段代码非常令人激动,因为它展示了如何将以往的点点点操作自动化。

const digit4Element = await driver.findElement(By.css('.digit-4'))
const digit2Element = await driver.findElement(By.css('.digit-2'))
const operatorMultiply = await driver.findElement(By.css('.operator-multiply'))
const operatorEquals = await driver.findElement(By.css('.operator-equals'))await digit4Element.click()
await digit2Element.click()
await operatorMultiply.click()
await digit2Element.click()
await operatorEquals.click()await retry(async() = > {const displayElement = await driver.findElement(By.css('.display'))const displayText = await displayElement.getText()expect(displayText).to.equal('84')
})

6. 集成测试

集成测试与端到端测试有些类似,大部分时候我们会涉及到dom操作,并且这部分操作很难抽离出来。我们当然也可以像端到端测试那样使用webdriver,但是这样测试的速度会慢很多。这里推荐一个非常棒的包:jsdom。用它自己的话说:这是在 NodeJS 中实现的 DOM。使用它的显著的好处是我们可以在 Node 中运行前端测试。

链接放这了,我就不再赘述它的使用方式了。

github of JSDOM


http://chatgpt.dhexx.cn/article/detoDxka.shtml

相关文章

前端测试都要测什么

单元测试,Unit Testing,简称 UT,是指对软件中的最小可测试单元进行检查和验证,这是最低级别的测试活动,前端开发中单元可以是一个 function 也可以是一个 class,也可以是一个组件。对他们的输出做断言检查&…

前端测试开发工具--mock 的使用

目录 1. 背景 2. Mock是什么 3. Mock能做什么 4. Mock实现方式 5. Mock市面上常见的解决方案 6. Python下unittest.mock使用 1. 背景 在实际产品开发过程中,某个服务或前端依赖一个服务接口,该接口可能依赖多个底层服务或模块,或第三方…

浅谈前端测试

浅谈前端测试 浅谈 TDD 和 BDD TDD Test Driven Development (测试驱动开发) 一种使用自动化单元测试来推动软件设计并强制依赖关系解耦的技术。使用这种做法的结果是一套全面的单元测试,可随时运行,以提供软件可以正常工作的反馈。大概的流程是先针对…

前端测试介绍

测试,作为软件工程的一项重要环节,用来保证项目的正确性,完整性,安全性和可靠性。 前端测试是前端工程化的重要环节,根据测试的粒度可以分为单元测试,功能测试(E2E测试),集成测试。 前端测试框架 单元测试 - Mocha - Jasmine - Jest 断言库 - chai - Jest - …

前端测试接口,POSTMAN一键调试

前端测试接口,POSTMAN一键调试 当我们在开发中,遇到接口有问题时,一般都会找后端battle一下,在这之前我们需要先确认问题,当我们浏览器不方便调试时,我们一般会借助postman,因为比较方便也比较…

【测试数据准备-绕过后端,前端测试】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、 Charles 简单介绍二、本文使用场景三、Charles 通过修改后端返回值,在前端展示。1.工具安装和注册2.使用端点功能修改接口返参数 总结 前言 测…

前端测试一共有哪几种?

前言 哈喽,大家好,我是海怪。 最近有不少朋友找到我聊了聊测试相关的内容,发现他们对测试的分类有些迷茫。实际上测试一共就 3 种:E2E,集成,单测,其它的功能测试、UI 测试、界面测试只是它们中…

聊聊前端测试那点事儿

虽然如今前端测试这个事已经被大家所认可了,但我见过做前端测试的团队并不多,能把前端测试做好的团队,就更加凤毛麟角了。 这个现象背后的逻辑是:编写前端测试其实非常困难。 在编写测试代码时,我们有很多事情要考虑…

前端测试如何做?

前端测试大家天天做。但是你知道前端测试是怎么做的吗? 什么是前端测试? 前端测试是测试图形用户界面(GUI)、web应用程序或软件的功能和可用性的一种测试技术。前端测试的目标是测试整体功能,以确保web应用程序或软件的表示层在连续更新中没有缺陷。 …

前端测试

1.什么是测试 测试是一种验证我们的代码是否可以按预期工作的方法。 换句话说就是写一些代码来验证一段代码是否能得到预期设计代码时所期望的结果。 被测试对象可以是样式,功能,流程,组件等。 2.前端测试的意义(这里主要指单元…

Oracle一次插入多条数据(批量插入)

语法: INSERT ALLINTO tableName (column1, column2, column_n) VALUES (expr1, expr2, expr_n)INTO tableName (column1, column2, column_n) VALUES (expr1, expr2, expr_n)INTO tableName (column1, column2, column_n) VALUES (expr1, expr2, expr_n) SELECT c…

oracle建表和插入数据

1.建表 File-->New-->Table 2.建表字段,如果写int的话,会报错 3.建立主键 4.点击应用 5.查看自己建好的表格 6.插入数据(日期这样子) INSERT INTO T_USER(USER_ID,USER_ACCOUNT,REAL_NAME,SEX,BIRTHDAY) VALUES(2,LiSi,李四,1,to_date(2020-2-2,…

Oracle数据库建表与插入数据

Oracle数据库建表和数据插入 本机环境表的建立插入数据 本机环境 windows10-64位 oracle12c 时间:2020-05-26 使用SQL Developer 表的建立 create table tableName ( 属性名 类型 约束, 属性名 类型 约束, . . . 属性名 类型 约束);如&…

oracle一次插入多条数据(insert all)

分享一个零基础,通俗易懂,而且非常风趣幽默的人工智能教程(如不能直接点击访问,请以“右键”->“在新标签页中打开链接”方式打开)网站,网址:https://www.cbedai.net/gnailoug/ 问题 公司的项目,有个功…

oracle数据库创建表并插入数据

这里以创建一个学生表student为例子,表里面字段有id,name,sex,age,math,english,其中id是主键,其他的不为空,语法如下所示: create table student(id number…

Oracle数据库----表中数据的操作(插入、更新、删除数据)

文章目录 一、插入数据插入多行数据的简单方法:1、将表一的全部数据添加到表二中创建副本Courses1,只复制Courses的结构将Courses表中的数据拷贝到Courses1中创建副本的同时复制结构和数据 2、一次性向单个或多个表中插入不同的数据 二、更新数据使用UPD…

Vue 视频教程分享

轻量级MVVM框架Vue.js快速上手(MVVM、SEO单页面应用、SSR服务器端渲染、Nuxt.js) 大小:6.62G 解压密码:无 链接:https://pan.baidu.com/s/1uBAxS0RvyXCD8uoFU7NXQA 提取码:h4fd

Vue零基础实战教程

Vue零基础实战教程 带有基本 Vue js 应用程序的 Vue。Vue.js 是一个流行的前端 JavaScript 框架。学习vuejs,成为vue开发者 课程英文名:Vue from Scratch with Real Life Vue JS Web Application 此视频教程共8.0小时,中英双语字幕&#x…

Vue基础教程

title: Vue基础教程 date: 2022-01-26 21:09:30 tags: [前端框架,Vue] categories: 前 端 cover: Vue基础入门 基础知识: HTMLJavaScriptCSSNode环境和npm(依赖管理 )webpack(可选) 官方文档: 学习任何…