摸爬滚打系列——React 调度原理

前言

最近团队落地实践了前端单元测试和 E2E (端到端) 测试方案,在此之前我基本没有在实际项目里用过自动化测试方案,总觉得这类方案耗时太大,没什么收益,但自从写自动化测试代码两个月以来,我发现还是有一定收益的,下面是我的一些思考和总结,希望对大家有一点点帮助。

什么是自动化测试

在正常的软件开发流程中,我们一定会有一个很重要的环节那就是测试,而对于一个大型项目来说,测试的环节尤为重要,它是软件发布前最后一个“关卡”,也是我们软件质量的重要保障,所以我们通常会留一些时间用于软件测试。测试的方式主要分为两大类:人工测试自动化测试

  • 人工测试:通过开发人员或测试人员与程序的交互来完成,即手动操作验证。
  • 自动化测试:通过自动化脚本与程序的交互来完成,除了刚开始编写的自动化脚本时间,基本上无需手动操作。

那自动化测试解决了什么问题呢?

解决了什么问题

假设有一个前端开发工程师 A 和一个测试人员 B,A 在开发完一个模块后往往会在页面上操作一下页面的流程,输入数据,查看页面是否正常工作,假如他开发的这个模块又依赖于之前已有的模块,于是他又测试了一下以前的模块,防止带来关联改动的 BUG。

A 测试完成之后,他推送了代码到远程仓库并合入稳定分支。测试 B 拉取仓库,然后部署一个测试环境,接着按照之前写的测试用例一条条去验证功能,测试 B 发现也有关联改动于是也顺带验证了之前的功能…

这种测试方式就是人工测试,简单直接,但是很繁琐,除了模块的基本功能测试,还需要对以前的功能做回归测试,如果这个模块的功能很复杂,比如一个很大数据量的表单输入,那耗费的时间就更多了,如果碰上项目紧急,就难免就导致天天加班去搞测试,而且很容易导致功能漏测,从而引发质量问题。

终于 A 实在忍受不了这种手动重复点击页面的操作了,于是决定在下一个迭代接入前端自动化测试。首先在确认了迭代二的需求之后,测试首先写好了测试需求用例,并且给产品线中的人做了评审,确定需求最终的验收条件。前端工程师 A 拿到测试给的需求后,并没有着急写代码,而是先做好相关的需求分析和模块设计,接着开始编写自动化脚本。然后完成所有的功能编码后,在本地触发脚本跑通所有的测试用例,确认没有问题后,推送到远程仓库。

回归测试是指 修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误

此时远程仓库也有一套流水线,会启动一个前端测试环境,然后自动打包前端代码,触发自动化测试脚本。如果该分支代码成功跑过了流水线,接着在 Code Review 环节(如果有)再审核代码,最后才会被合入主干稳定分支。

上面这种方式就是自动化测试的方案(前端),这种方案基本上能做到不漏测一个功能,而且不需要我们手动去输入数据和点击页面去验证了,提升了代码的质量。但是也是有缺点的:

  • 要保证写的测试脚本覆盖所有的需求点,不然就是自欺欺人了(比如 100% 的测试覆盖率,若漏写了测试用例就完犊子了…)。
  • 需求变更的时候要及时去更新需求测试脚本。
  • 整个自动化流程的基建设施要完善,比如 CI/CD 流程,只有自动化脚本没有 CI/CD 流程效率会低很多。
  • 业务繁忙,没时间写测试脚本。
  • 测试脚本有一定的上手成本。

即使满足了上述条件下,还是存在一些问题的:自动化测试那么好,但是要如何做呢?必须要全部测试吗?特殊场景的测试问题该如何解决呢?下面就来介绍一下前端测试的一些方法和工具使用。

自动化测试的应用场景

前端自动化测试方法主要是两大类,白盒测试黑盒测试(当然还有其他更细分的测试比如灰盒测试,这里不多说了,因为大学的测试理论忘的差不多了😂)。

  • 白盒测试:说白了就是代码的逻辑是否正确,流程逻辑,函数调用,异常处理等等,比如常见的单元测试。
  • 黑盒测试:主要是对一个功能的验证,不关心代码的具体实现,比如端到端测试(E2E,也是集成测试的一种类别)。

当然,细分的类别我们能接触到的就是单元测试集成测试UI测试端到端测试了,它们各有千秋,但是在某些场景都有不可替代性。下面我通过几个场景来简单介绍一下它们的概念。

单元测试的场景

假如我们要写一个数字类型的加法函数,我们要先想好它的输入输出

  • 输入:接受两个数字参数。
  • 输出:输出两个参数的和。

于是我们的代码是:

function sum(a, b) {return a + b;
}

export default sum; 

而对应的测试代码(以 Jest 为例)是:

import sum from './sum';

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

当然你也可以做一些边界值的测试,比如输入非数字类型的参数和空值,有兴趣的同学可以继续补充。

这就是单元测试的一种表现形式,它一般是对程序最小单元运行测试的过程,除此之外我们可能会接触到的其它单测场景:

  • 组件的单元测试:UI 组件、无状态组件、基础组件。
  • 纯函数的单元测试,我们可能会封装一些 util 工具等等,但是要保证我们写的函数是易于测试的,即没有副作用,函数的输入和输出是稳定的。

单元测试的优点:

  • 测试速度很快。
  • 代码覆盖率较高。
  • 有助于模块的设计。
  • 易于代码维护。

而缺点就是无法验证多个单元运行到一起是否正确,能做到这一点的是我们要介绍的集成测试。

集成测试/端到端测试的场景

集成测试是把不同的模块集成在一起,来测试模块与模块之前的配合是否正常工作。比如在前端我们点击一个按钮会进行表单提交,而这涉及到按钮的点击事件是否正常,表单的校验或者发送请求是否正常触发。

E2E的定义和集成测试是差不多的,它们通常都是站在用户视角并且以真正的运行环境来测试整个流程和功能的。集成测试和端到端的定义的边界是较模糊的,所以我们可以放在一起介绍。下面是一个用户使用某个系统的简单场景:

  • 访问某个系统主页
  • 点击某个元素,然后进入另外一个页面

那么它的测试代码可以这么写(以 Cypress 为例):

describe('My First Test', () => {it('clicking "type" navigates to a new url', () => {// 1.访问 https://example.cypress.io -> 模拟用户输入 URLcy.visit('https://example.cypress.io')// 2.点击某个元素 -> 模拟用户点击cy.contains('type').click()// 3.跳转新页面的断言// includes '/commands/actions'cy.url().should('include', '/commands/actions')})
}) 

做自动化测试一般有一个流程:输入 - 断言 - 验证。不管是单测还是 E2E 都可以遵循这个原则,如果不知道如何开始,可以考虑我们的预期结果是什么,以终为始,再去慢慢实现函数或组件的具体功能,这就是 TDD 的一种模式,这在后面我们会介绍到。

相信大家看了上面两个案例之后对测试有了一定的感性认知了,那么前端自动化测试框架或工具有哪些,以及怎么上手使用呢?下面我给大家简单介绍一下我所了解的一些工具吧。

自动化测试框架介绍

单元测试框架

目前市面上比较流行的一些前端单元测试框架主要是:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值