「技术分享」前端搞懂测试

「技术分享」前端搞懂测试

团队内技术分享,2022-01-12

测试的类型

  • 单元测试: 测试一段代码(通常是一个对象或函数) ,与其他部分隔离开来
  • 集成测试: 将多个部分放在一起进行测试
  • 功能测试(也称为e2e测试): 对整个应用程序进行自动测试,这些测试通常忽略整个应用程序的内部结构,而是从外部像黑盒子一样查看它们。

详细了解:

测试流派划分

TDD (Test Driven Development)

误区:先写测试,后写代码的实践指的是测试先行开发,而非测试驱动开发。

体现驱动这个动作,才能称为测试驱动开发。

image

红,表示写了一个新的测试,测试还没有通过的状态;绿,表示写了功能代码,测试通过的状态;而重构,就是再完成基本功能之后,调整代码的过程。

测试驱动开发 就是多了这个步骤。在功能完成而且测试跑通之后,我们还会再次回到代码上,处理一下代码上写得不好的地方,或是新增代码与旧有代码的重复。因为我们第二步“绿”的关注点,只在于让测试通过。

在测试驱动开发中,重构与测试是相辅相成的:没有测试,你只能是提心吊胆地重构;没有重构,代码的混乱程度是逐步增加的,测试也会变得越来越不好写。

TDD 也可称为测试驱动 设计,许多人抗拒测试有两个主要原因:第一,测试需要“额外”的工作量。这里我特意把额外加上引号,因为,你也许本能上认为,测试是额外的工作,但实际上,测试也应该是程序员工作的一部分,这在上一篇文章中我已经讲过。

第二,很多人会觉得代码太多不好测。之所以这些人认为代码不好测,其中暗含了一个假设:代码已经写好了,然后,再写测试来测它。

如果我们把思路反过来,我有一个测试,怎么写代码能通过它。一旦你先思考测试,设计思路就完全变了:我的代码怎么写才是能测试的,也就是说,我们要编写具有可测试性的代码。 用这个角度,测试是不是就变得简单了呢?

TDD vs ATDD vs BDD

  • Acceptance Test Driven Development(验收测试驱动开发)
  • Behavior-Driven Development (行为驱动开发)

| 区别项 | ATDD | TDD | BDD | | --- | --- | --- | --- | | 参与者和范围 | 业务用户,开发人员,测试人员之间的沟通机制以确保需求得到充分记录 | 开发人员和测试人员之间的开发方法,以创建良好的代码单元(模块,类,功能) | ATDD和TDD的组合。 | | 重点 | 专注于提取用户验收测试中的要求并用于推动开发。是一种使客户进入设计阶段的技术 | 一种模式和范例 | 专注于客户和开发者的系统行为方面,仍然是偏向于不断测试的实践来引导客户进入测试阶段,并通过逐步关注其行为进行认证。 | | 敏捷步骤 | 1. 讨论 2. 开发 3.发布 不断重复 | 1. 测试 2.编码 3.重构 不断重复 | 按预期行为逐步构建功能。它是TDD和编写使功能/行为失败的测试的延伸 | | 输入文档 | 验收标准+示例(数据和方案)=验收测试需求文档将作为开发和测试的基础。 | 需求文档 | 用GWT格式书写的实例化文档,有时也需要验收标准 | | 自动化要求 | 不是必须,但是可在回顾测试时实现 | 必须 | 必须 | | 故事/特性/测试地图 | 每个故事都应对应一个验收测试 | 每个功能都需要对应一个测试 | 每个故事应对应一个行为测试 | | 最终用户 | 客户 | 开发人员,测试人员 | 客户和开发者 |

如何通过测试左移应对新的开发模式?

什么是测试左移和测试右移?

测试左移和右移,就是把测试的范围从传统测试的节点中释放出来,向左和右扩展。

向左扩展,就是让测试介入代码提测之前的部分。比如,扩展到开发阶段,在架构设计时就考虑产品的可测试性,并尽量进行开发自测等。另外,测试可以更进一步扩展到需求评审阶段,让测试人员不只是了解需求,更要评估需求的质量,比如分析需求的合理性以及完整性等。

类似的,测试右移,是让测试介入代码提测之后的部分。比如,测试人员在产品上线过程中,利用线上的真实环境测试。另外产品上线之后,测试人员仍然介入,通过线上监控和预警,及时发现问题并跟进解决,将影响范围降到最低。这样一来,测试人员不但有更多的时间进行测试,还能发现在非生产环境中难以发现的问题。

测试左移的原则和实践

  • 调整团队对测试的态度;
  • 把测试添加到开发和产品需求步骤中;
  • 频繁测试,快速测试。

测试左移原则一:调整团队对测试的态度

调整团队对测试的态度,打破竖井的工作方式,是测试左移的前提。**一个有效的办法是,按照功能的维度管理团队,让整个功能团队对产品负责。**也就是说,如果产品质量出现问题,不只是测试团队“背锅”,而是会影响整个功能团队的绩效。同时,让质量问题的直接责任人承担更多的责任,来进一步增强团队成员的责任心。这种利益绑定的办法,虽然简单但非常有效,只不过出现质量问题时要记得进行根因分析,以避免再次出现类似问题。

**另外,还要改变团队成员对测试工作的认知。**传统的工作方式中,我们通常认为发现 Bug 最重要,但其实为了提高产品质量,更重要的是预防 Bug。所以说,在测试左移的过程中,我们应该更聚焦在预防 Bug 上。

测试左移原则二:把测试添加到开发和产品需求步骤中

测试左移的第一步,是把测试工作融入到开发步骤中。常用的办法是,让测试人员参与到开发阶段的方案设计中,了解开发的实现方式。因为很多开发人员可能只熟悉他负责的那一部分,而测试人员往往对全局更加了解,所以测试人员要评估改动范围以及是否有遗漏的模块和系统。 全栈开发的场景主要是,通过运维团队提供工具和支持,让开发人员尽量参与到运维工作中去。对于测试来说,也是同样的道理。我们可以让测试团队转型,进行工具开发,并更多地去支持专项测试,比如性能测试、安全测试等,通过“使能”的办法,让开发人员完成功能测试,包括单元测试、集成测试等。

**说到让开发人员完成部分测试工作,常常会听到很多质疑声。**反对者认为,测试人员的心理模型跟开发人员不一样,他们更倾向于去找问题。而开发人员面对自己开发的产品,潜意识里就不愿意去找问题,比如,他们不愿意专门尝试各种边界输入进行测试,而把自己开发的功能搞崩溃。 如果你能够把开发人员的责任界定得很清楚,谁开发的产品谁要保证质量,那么开发人员自然而然地就会去尝试做好测试,比如进行边界测试。而且,开发人员最了解自己写的代码,所以他能够最高效地对自己的代码进行测试。

**测试左移到了开发阶段之后,再往左移一步就到了产品设计阶段,**在这里,测试人员除了解需求外,更重要的是评估需求的质量。

测试左移原则三:频繁测试,快速测试

测试左移的第三个重要原则是,频繁测试、快速测试。在测试左移之前,我们需要等待提测,比较被动,不能频繁测试。但测试左移到开发阶段之后,我们就有了很大的自由度去频繁运行测试,从而更好地发挥测试的作用,尽早发现更多的问题。

这里最重要的方法具体包括:

  • 规范化、自动化化本地检查;
  • 建设并自动化代码入库前的检查流程;
  • 提供快速反馈,促进增量开发。

持续集成(CI)、持续部署(CD)

大致了解:

image

更多推荐:

前端测试介绍

测试工具框架、工具库很多,可以将他们按以下分组方式挑选使用:

推荐参考文章:

代码演示

单元测试Chai+Mocha

Jest 测试

Puppetter 自动化测试

相关其他了解:PhantomJS、Nightmare、Selenium 推荐Puppetter实践文章:京喜前端自动化测试之路

Puppeteer 是一个 Node 库,它提供了一套高阶 API ,通过 Devtools 协议控制 Chromium 或 Chrome 浏览器。Puppeteer 默认以 Headless 模式运行,但是可以通过修改配置文件运行“有头”模式。

官方特性说明:

  • 生成页面 PDF;
  • 抓取 SPA(单页应用)并生成预渲染内容(即“ SSR ”,服务器端渲染);
  • 自动提交表单,进行 UI 测试,键盘输入等;
  • 创建一个时时更新的自动化测试环境,使用 JavaScript 和最新的浏览器功能直接在最新版本的 Chrome 中执行测试;
  • 捕获网站的 Timeline Trace,用来帮助分析性能问题;
  • 测试浏览器扩展。

demo演示介绍

const puppeteer = require('puppeteer');

const loginPageUrl = 'https://xxxx.leekhub.cn/user/login';

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto(loginPageUrl, { waitUntil: 'networkidle2' });
  await page.setViewport({
    width: 1440,
    height: 760,
  });
  // 如果5s不打开页面超时退出
  await page.setDefaultTimeout(5000);
  // 进入页面后,输入账号密码,点击登陆按钮
  await page.type('#username', 'admin', { delay: 100 });
  await page.type('#password', 'Admin@xxxx', { delay: 50 });
  await page.click('.ant-btn.ant-btn-primary.ant-btn-lg'); // 点击登陆按钮
  // 导航跳转结束,“点击”进入 客商管理
  await page.waitForSelector('[href="/merchant-manage"]');
  await page.click('[href="/merchant-manage"]');
  // 正常跳转比较快,延时为了演示看菜单跳转效果
  await page.waitFor(5000);

  await page.waitForSelector('[href="/merchant-manage/driver"]');

  // 打开机手管理菜单,jquery写法
  const aElement = await page.$('[href="/merchant-manage/driver"]');
  await aElement.click();
  // await page.click('[href="/merchant-manage/driver"]');

  // 演示截屏
  // 演示代码错误怎么看。
  // 演示爬虫,抓取数据
  // await browser.close();
})();

CI 自动化执行测试

实操 Github Action

推荐书籍

参考文献

除文章中参考链接,还有:

  • 极客专栏《10x程序员工作法》
  • 极客专栏《研发效率破局之道》

欢迎前往原文讨论:https://github.com/giscafer/blog/issues/57

相关文章