本文主要首先主要介绍了什么是自动化测试,接着对常用的自动化测试框架进行了对比分析,最后,介绍了如果将自动化测试框架Cypress运用在项目中。

一、自动化测试概述

为了保障软件质量,并减少重复性的测试工作,自动化测试已经被广泛运用。在开始学习自动化测试之前,我们很有必要先搞清楚这几个问题,什么是自动化测试?为什么要做自动化测试?哪些项目适合做自动化测试?

1、什么是自动化测试

    自动化测试是一种测试方法,是指使用特定的软件,去控制测试流程,并比较实际结果与预期结果之间的差异。通过将测试自动化,可以把人对软件的测试行为转化为由机器自动执行测试的行为,从而替代大量的手工测试操作,使得测试可以快速,反复的进行。

关于自动化测试,有一个测试金字塔模型,该模型把测试从下到上分为了单元测试、集成测试和端到端测试(E2E测试/UI界面测试)。越往金字塔底层,测试成本越低,效率也越高,而越往金字塔的顶层,测试成本会逐渐增高,收益也会越低。

  • 单元测试

单元测试又称为模块测试,主要针对程序中最小可测试单元(一般指方法,类)的测试,具备投入小、收益产出高的特征,可以较早期地发现代码缺陷,适用于公共函数库的测试。

  • 集成测试

集成测试主要包括模块接口测试,子功能模块集成起来的功能模块测试等,目的是为了验证在单元测试的基础上,所有模块集成起来的子系统、子功能是否仍然满足质量目标。

  • 端到端测试

端到端测试的主要目的是从软件使用者角度来检验软件的质量,如打开浏览器,进行一系列的操作,验证界面或功能是否符合预期。

不同类型的项目,具有不同的测试场景,因此也需要采用不同的测试类型。对于开发人员来说,单元测试专注于代码底层,可能是一种比较友好的选择。但是站在产品的角度上,也许端到端测试(E2E)是更好的选择,更能保障产品功能符合预期。

讲完了自动化测试类型,我们再来看看测试中常用的测试模式,一般常用的测试模式包括TDD和BDD两种。

  • TDD

TDD(测试驱动开发,Test Driven Development),TDD是指先写测试用例代码,再写功能代码,并且不断的重复上述步骤直到完成开发工作。TDD一般结合单元测试使用,是白盒测试。

  • BDD

BDD(行为驱动开发,Behavior Driven Development),BDD是指先写功能代码,再写测试用例代码,BDD一般结合集成测试或端到端测试使用,是黑盒测试。

当然,是选择TDD还是BDD,也是需要从项目的实际角度出发考虑,再做选择。

2、为什么要做自动化测试

接下来,我们再来聊聊为什么要做自动化测试?在实际的项目开发中,我们常常会遇到以下问题:

  • 产品迭代频繁

迭代过程中不可避免的需要新增功能或修改功能,怎么保障新功能的发布不会影响原有功能呢?

  • 多人共同参与开发,代码维护难

项目开发过程中多人参与开发,人员变动频繁,开发过程中可能出现误删或误改他人代码逻辑的问题,如何保障代码的质量和可靠性?

  • 测试人力不足,回归测试耗时耗力

为了解决上面提到的两个问题,其实方法很简单,就是每次新功能发布后,都对原有功能再进行回归测试。但是又可能遇到测试人力不足的情况,自己手动进行回归测试又耗时耗力,如何才能减少重复性工作,提高效率呢?说到这里,自动化测试就派上用场啦~

那项目引入自动化测试有什么好处呢?自动化测试的好处主要包括了以下几点。

  • 验证代码正确性,保障产品质量

可以验证代码或产品功能的正确性,确保每次产品迭代,新功能和原有功能能够正确集成,保证产品质量。

  • 提高测试效率

编写的测试用例具有一次编写,多次运行的特点,通过执行测试脚本,可以实现使得测试快速,反复的进行,可以替代大量的重复性手动测试工作,提高效率。

  • 起到文档作用

编写的测试用例可以起到文档的作用,有利于项目后续的维护。

3、哪些项目适合引入自动化测试

既然自动化测试有这么多好处,那是不是所有项目都适合引入自动化测试呢?当然不是!自动化测试需要进行测试用例的编写,需要一定的开发成本,我们需要立足于项目本身,再来决定是否适合引入自动化测试。

  • 适合引入自动化测试的项目

1)产品周期较长,需要不断进行迭代/重构的项目。2)公共库类的开发维护。

  • 不适合引入自动化测试的项目

1)产品周期过短的项目。2)需求变动过于频繁的项目。

二、前端自动化测试框架选择

在明确了我们的项目有必要引入自动化测试之后,就需要选择一款自动化测试框架或工具来帮助我们完成自动化测试工作啦~

1、测试框架对比

下面主要对比了现在常用的Web前端自动化测试框架,如果需要了解更多的框架,可以参考测试框架选型

  Jest Mocha Selenium/WebDriver Nightwatch TestCafe Cypress
支持测试类型 单元测试 单元测试 E2E测试 E2E测试、Node.js单元和集成测试 E2E测试 单元测试、集成测试、E2E测试
支持语言 JS、Node JS、Node Java、Python、C#、JS JS、Node JS、TypeScript JS
是否支持可视化测试
是否自带断言库
是否开箱即用 是(安装配置繁琐)
录制生成脚本 / / 支持 不支持 不支持 不支持
Github Star 35.2k 20.5k 20.8k 10.7k 8.9k 31.3k
文档 Jest文档 Mocha文档 Selenium文档 Nightwatch文档 Testcafe文档 Cypress文档

在上述框架中,由于Cypress能够同时支持单元测试、集成测试和E2E测试,提供了一套完成的测试解决方案,能够满足我们的需求。此外,Cypress支持JS编写测试用例,支持Jquery元素定位选择器,支持Headless和CI持续集成,运行速度快,上手成本低,并且具有可视化调试界面,方便定位问题。因此决定尝试将Cypress运用到项目中。

三、Cypress实践

接下来,主要介绍如何将Cypress运用在项目中。

1、Cypress安装

在安装Cypress时,可以直接在原有的项目上进行安装,也可以另起一个项目安装。

npm install cypress --save-dev

2、Cypress启动

Cypress主要包含以下两种启动方式:

1)命令行执行npx cypress open:会在浏览器打开测试用例集的界面,需要手动运行。

2)命令行执行npx cypress run:会以无头浏览器模式运行指定的所有测试用例,没有可视化界面,但运行过程中会录制整个测试过程的视频,可在cypress/videos目录下查看。

当然,除了直接在命令行运行上述命令,也可以通过配置package.json的scripts字段来定义启动方式。

"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"cypress:open": "npx cypress open",
"cypress:run": "npx cypress run"
}
  • 可视化界面运行

如果我们需要在可视化界面进行测试,在配置好package.json后,只需要执行npm run cypress:open,就可以启动Cypress,实现可视化调试,如果在启动的过程中遇到以下错误,可以先执行npx cypress install -force,再重新启动Cypress。

如果成功启动Cypress,将会看到以下界面,examples目录下是cypress自带的测试用例演示代码(如果后面不需要,我们可以将这些测试用例删除),点击其中的某个测试用例,将会自动打开浏览器运行测试用例。

如果我们是第一次启动Cypress,会发现在项目根目录下也自动生成了cypress.json配置文件和cypress目录。其中,integration文件夹就是我们用来存放测试用例的目录,可以在cypress.json中自定义这些默认目录的命名。

  • 无头浏览器模式运行

如果我们想以无头浏览器模式运行,在配置好package.json后,需要执行npm run cypress:run,Cypress就会以无头浏览器的模式运行指定的所有测试用例。

3、编写测试用例

接下来以验证百度页面的搜索功能为例,演示如何编写测试用例,测试用例可以以.spec.js或.js结尾命名,并放入cypress/integration中。

项目目录如下所示,在cypress/integration中创建test.js或test.spec.js测试用例文件。

接着,可以在test.js中开始编写测试用例,Cypress支持Jquery元素选择器及汉字选择器,并且也支持链式操作,此外,由于Cypress拥有自动等待机制,我们无须在测试中添加wait或sleep,Cypress会自动等待元素至可操作状态时才执行命令或断言

/// <reference types="cypress" />

context('百度页面测试', () => {
it('访问百度页面,验证搜索功能', () => {
cy.visit('https://www.baidu.com').then(() => {
// 1. 输入搜索内容
cy.get(".s_ipt").should("exist").type("Cypress自动化测试");
// 2. 点击百度一下按钮
cy.get(".s_btn").contains("百度一下").should("exist").click();
// 3. 验证搜索内容不为空
cy.get("#content_left").find("div").then(ele => {
expect(ele.length).gt(0);
});
});
});
});

编写完上述代码,我们就可以直接启动Cypress运行啦,当然,我们也可以根据实际需要在cypress.json进行一些配置,下面给出了一些常用的配置,可以在Cypress文档查看更多配置。

最后,执行npm run cypress:open启动Cypress,启动成功后,我们就可以看到以下界面,点击test.js,就会在浏览器中运行该测试用例。

在测试用例执行的过程中,每一步操作都会被记录下来,可以点击左边的界面对每一步的操作进行回看,可以帮助我们快速定位问题。

4、Cypess文件上传/下载

在实际的使用过程中,我们通常也需要验证文件上传或下载功能,而Cypress也能够满足这些需求。

    1)文件上传

首先需要安装cypress-upload-file插件。

npm install cypress-upload-file --save-dev

将要上传的文件放到cypress/fixtures中。

编写测试用例代码。

/// <reference types="cypress" />

context('文件上传', () => {
it('验证文件上传功能', () => {
// 访问页面,此处步骤省略
let file = "file/cover.jpg";
cy.get("input[type='file']").attachFile(file);
// 执行断言,此处步骤省略
});
});

    2)文件下载

若我们在运行测试用例的过程中存在文件下载操作,Cypress会自动在cypress目录下创建一个downloads目录,所下载的文件会自动保存在该目录中。

可以在测试用例中读取并解析下载的文件。

/// <reference types="cypress" />

const path = require("path");

context('文件下载', () => {
it('验证文件下载功能', () => {
// 访问页面,执行下载操作,此处步骤省略
const downloadsFolder = Cypress.config("downloadsFolder");
const downloadedFilename = path.join(downloadsFolder, "下载文件.xls");
// 读取文件
cy.readFile(downloadedFilename).then(data => {
// 执行断言,此处步骤省略
});
});
});

5、Cypress测试报告

在执行完自动化测试后,我们通常都希望能够得到一份详细的测试报告,而Cypress也能够提供这个功能。Cypress除了内置的测试报告,也支持用户自定义报告格式。

    1)内置的测试报告

Cypress内置的测试报告主要包括了spec格式报告(在控制台窗口输出嵌套分级视图),json格式报告(在控制台窗口输出一个大的json对象)和junit格式报告(输出一个xml文件)。以spec格式报告为例,在启动cypress时加上以下参数即可。

    2)自定义的测试报告

常用的自定义测试报告有Mochawesome报告,Mochawesome是与Mocha一起使用的自定义报告程序,并与mochawesome-report-generator结合使用以生成独立的HTML/CSS报告。

安装mocha和mochawesome。

npm install mocha --save-dev
npm install mochawesome --save-dev

修改启动参数。

运行npm run cypress:run,执行结束后,会在项目根目录下生成mochawesome-report目录。

在浏览器中打开mochawesome.html,就可以查看可视化测试报告。

四、编写可维护的测试脚本

在实际编写测试用例的过程中,随着页面的增多,我们常常会遇到以下这些问题,而这个时候,如何编写可维护的测试脚本,方便后期维护,也显得非常重要,这里也总结了实际开发中的一些经验。

1、测试用例代码结构组织

在编写测试用例时,我们可以一个页面对应一个测试文件,也可以同个功能模块的页面一起对应一个测试文件,并且和平时开发中所采用的代码组织结构类似,将不同的测试文件划分到对应的目录下进行管理,方便后期的维护。

2、页面选择器统一管理

在E2E测试中,我们通常需要获取页面元素,才能够进行点击等操作。而Cypress支持Jquery选择器,我们可以通过元素的class或id定位元素。但是一旦页面的类名或id发生变化,我们不得不修改对应页面的所有测试用例。

在编写测试用例的过程中,我们可以将页面选择器进行统一管理,实现类名或id选择器和逻辑代码的分离。对于每个页面或者每个测试文件,可以创建一个对应的xxxControl.js文件,在该文件中,将会定义一个json对象并且export出来,其中,key为我们自己定义的选择器名称,而value值对应页面中实际的class或id

由于目前项目中使用到了iview组件库,因此也提取出了commonControl.js,对iview的选择器进行统一管理。

由于每个页面都采用到了iview组件,因此每个页面或每个测试文件对应的control.js都需要将上面的commonControl.js引入进来。

最后,每个测试文件只需要引入对应的control.js,就可以通过自己定义的key值获取页面真正的class或id。

上面的方法看起来虽然麻烦了点,但是有两个好处,首先,采用自己定义的key值,更容易方便我们记忆,可以减少编写测试用例过程中反复查看页面元素对应的class或id名。其次,当页面的类名或id发生变化时,我们只需要修改页面对应的control.js文件就可以,而不用修改所有的测试用例文件,有利于后续的维护。

3、路径名及接口统一管理

在编写测试用例的过程中,我们通常需要使用cy.visit()去访问某个页面,或者使用cy.request()去调用后台接口以请求数据或创建测试数据,对于页面url或后台接口api,我们也可以放入某个文件中进行统一管理。

4、代码复用

在测试的过程中,我们可能会注意到,不同的页面可能会存在一些相同的功能。比如像目前的项目中,不同的页面都需要对一些操作进行弹框确认或表单输入,而在验证弹框功能是否正确的过程中,我们都需要对弹框执行点击确定按钮、点击取消按钮、点击关闭按钮等操作,而这个时候就可以采用面向对象编程的方法实现代码的封装和复用

定义一个弹框类,并且定义属性和方法。

在测试文件中,需要实例化对象,并调用相关的方法完成某个操作。

当然,有些方法并不是所有的页面都共有的,但是在某个页面或功能中会反复使用到,因此也可以为每个页面或每个测试文件单独封装相应的方法。比如为课程管理页面封装相应的通用方法。

以上就是关于将Cypress运用在项目中的一些总结,而如何将Cypress和CI/CD结合,并且实现自动化测试的定时执行,也是接下来需要继续完成的内容~

Web前端自动化测试Cypress实践总结的更多相关文章

  1. Web前端开发最佳实践(2):前端代码重构

    前言 代码重构是业内经常讨论的一个热门话题,重构指的是在不改变代码外部行为的情况下进行源代码修改,所以重构之前需要考虑的是重构后如何才能保证外部行为不改变.对于后端代码来说,可以通过大量的自动化测试来 ...

  2. web前端开发最佳实践笔记

    一.文章开篇 由于最近也比较忙,一方面是忙着公司的事情,另外一方面也是忙着看书和学习,所以没有时间来和大家一起分享知识,现在好了,终于回归博客园的大家庭了,今天我打算来分享一下关于<web前端开 ...

  3. Web前端优化最佳实践及工具集锦

    Web前端优化最佳实践及工具集锦 发表于2013-09-23 19:47| 21315次阅读| 来源Googe & Yahoo| 118 条评论| 作者王果 编译 Web优化Google雅虎P ...

  4. [转] Web 前端优化最佳实践之 Mobile(iPhone) 篇

    原文链接:http://dbanotes.net/web/best_practices_for_speeding_up_your_web_site_server_mobile.html Web 前端优 ...

  5. web前端自动化测试/爬虫利器puppeteer介绍

    web前端自动化测试/爬虫利器puppeteer介绍 Intro Chrome59(linux.macos). Chrome60(windows)之后,Chrome自带headless(无界面)模式很 ...

  6. 【社区公益】送《Web前端开发最佳实践》给需要的人

    算起来至今,我进入软件开发行业已经有11年之久.从最初的研究人工智能,到后来的Web开发,控件开发,直到现在纯粹的Web前端开发.虽然没有大的作品问世,但也是勤勤恳恳,踏实做事,低调做人.从来不吹牛逼 ...

  7. Web前端开发最佳实践系列文章汇总

    Web前端开发最佳实践(1):前端开发概述 Web前端开发最佳实践(2):前端代码重构 Web前端开发最佳实践(3):前端代码和资源的压缩与合并 Web前端开发最佳实践(4):在页面中添加必要的met ...

  8. Web前端开发最佳实践(9):CSS代码太太乱,重复代码太多?你需要精简CSS代码

    前言 提高网站整体加载速度的一个重要手段就是提高代码文件的网络传输速度.之前提到过,所有的代码文件都应该是经过压缩了的,这可提高网络传输速度,提高性能.除了压缩代码之外,精简代码也是一种减小代码文件大 ...

  9. Web前端开发最佳实践(8):还没有给CSS样式排序?其实你可以更专业一些

    前言 CSS样式排序是指按照一定的规则排列CSS样式属性的定义,排序并不会影响CSS样式的功能和性能,只是让代码看起来更加整洁.CSS代码的逻辑性并不强,一般的开发者写CSS样式也很随意,所以如果不借 ...

随机推荐

  1. Day16_94_IO_读取文件字节流read()方法(三)

    读取文件字节流read()方法(三) int read(byte[] bytes) 返回值为int类型, 该int类型数据表示每一次读取到的有效字节数,也就是读取到了几个字节, 一个都没读取到返回-1 ...

  2. 测试报告模板:HTMLTestRunner.py(新版)

    报告样式效果: 报告源码:HTMLTestRunner.py 1 """ 2 A TestRunner for use with the Python unit test ...

  3. 也谈如何写一个Webserver(-)

    关于如何写一个Webserver,很多大咖都发表过类似的文章.趁着这个五一假期,我也来凑个份子. 我写Webserver的原因,还得从如何将http协议传送的消息解析说起.当时,我只是想了解一下htt ...

  4. 【ElasticSearch】ES 读数据,写数据与搜索数据的过程

    ES读数据的过程: 1.ES客户端选择一个node发送请求,该请求作为协调节点(coordinating node): 2.corrdinating node 对 doc id 对哈希,找出该文档对应 ...

  5. 手动脱Mole Box V2.6.5壳实战

    作者:Fly2015 这个程序是吾爱破解脱壳练习第8期的加壳程序,该程序的壳是MoleBox V2.6.5壳,之前也碰过该种壳但是这个程序似乎要复杂一点. 首先对加壳程序进行侦壳处理. Exeinfo ...

  6. hdu3987 最小割边数

    题意:      是让你求最小割之后问最小割的最少边数是多少,因为最小割不是唯一的,所以存在最小边数的问法.思路:      两个方法,一个是先一遍最大流,然后把割边全都改成流量1,其他的全都改成流量 ...

  7. 续订Jetbrain学生包

    今天打开IDEA和Pycharm都不约而同的告诉我我的账号无法使用学生包了 此刻我的内心是: 冷静下来我算了算,嗷,原来是一年的订阅期到了,那就简单了,直接续订吧,唉.其实续订和重新认证是一样的. 首 ...

  8. GDOI2021 游记

    蹭了个名额去参加 \(\text{GDOI}\) \(\text{tg}\),体验了一下大佬的生活/kk (以下试题皆为 \(\text A\) 卷 DAY -1 不知道要复习什么.本来没有机会来参加 ...

  9. 数据库调优(二)Inner Join Merge Join Hash Match

    T-SQL 的编码习惯以及规范,影响的是查询优化器对执行计划的选择 健壮的SQL语句,更稳定.更高效 SELECT 几个部分: - 查询的数据来自什么表 - 需要查询表中哪些字段 (尽量不使用类似于 ...

  10. 高性能MySQL-索引

    创建索引-高效索引 1.1 索引初体验 1.1.1 介绍 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针. 索引的作用是做数据的快速检 ...