《软件测试52讲》学习笔记(四)

因为报了一个课程,记录一些自己觉得有用的东西,课程链接:

https://time.geekbang.org/column/article/10150

二、测试基础知识篇

  • 第十小节  软件测试工程师需要掌握的非测试知识有哪些?

你可以参照下面这个比喻,来理解开发工程师和测试工程师的对知识的要求:开发工程师通常是“深度遍历”,关注的是“点”;而测试工程师通常是“广度遍历”,关注的是“面”。

1、测试工程师需要掌握的非测试知识主要有哪些呢?

  • 小到 Linux/Unix/Windows 操作系统的基础知识,Oracle/MySQL 等传统关系型数据库技术,NoSQL 非关系型数据库技术,中间件技术,Shell/Python 脚本开发,版本管理工具与策略,CI/CD 流水线设计,F5 负载均衡技术,Fiddler/Wireshark/Tcpdump 等抓包工具,浏览器 Developer Tool 等;
  • 大到网站架构设计,容器技术,微服务架构,服务网格(Service Mesh),DevOps,云计算,大数据,人工智能和区块链技术等。

1.1、网站架构的核心知识

  • 比如,如果你不清楚 Memcached 这类分布式缓存集群的应用场景和基本原理,如果你不清楚缓存击穿、缓存雪崩、缓存预热、缓存集群扩容局限性等问题,你就设计不出针对缓存系统特有问题的测试用例;
  • 再比如,如果你对网站的可伸缩性架构设计不了解,不清楚应用服务器的各种负载均衡实现的基本原理,不了解数据库的读写分离技术,你就无法完成诸如故障切换、动态集群容量伸缩、服务降级等相关的测试,同时对于性能测试和全链路压测过程中可能遇到的各种瓶颈,也会很难定位和调整。

1.2、容器技术

与传统的虚拟机相比,容器技术在轻量化程度、资源占用、运行效率等方面具有压倒性的优势。

作为新时代的测试开发工程师,你必须像熟练使用 VMware 一样,掌握 Docker 和 Kubernetes 的原理和使用方法。

此处附上Docker的官网链接:https://docs.docker.com/get-started/

1.3、云计算技术

为什么要懂得云计算技术呢?

一方面,很多企业,尤其是互联网企业都在尝试“上云”,显然,作为测试工程师,你必须理解服务在云端部署的技术细节才能更好的完成测试任务。

另一方面,测试基础服务作为提供测试服务的基础设施,比如测试执行环境服务(Test Execution Service)和测试数据准备服务(Test Data Service)等,也在逐渐走向云端。

1.4、DevOps 思维

DevOps 的具体表现形式可以是工具、方法和流水线,但其更深层次的内涵还是在思想方法,以敏捷和精益为核心,通过发现问题,以系统性的方法或者工具来解决问题,从而实现持续改进。

对于 DevOps,我建议的学习路径是,你可以从深入掌握 Jenkins 之类的工具开始,到熟练应用和组合各种 plugin 来完成灵活高效的流水线搭建,之后再将更多的工具逐渐集成到流水线中以完成更多的任务。相信通过这样的学习,当你再面对相关的测试工作时,必然可以轻松应对。

1.5、前端开发技术

从测试工程师的角度来讲,如果你能够掌握前端开发技术,也就意味着你可以更高效地做前端的测试,更容易发现潜在缺陷。同时,你还可以自己构建测试页面,来完成各类前端组件的精细化测试,大大提高测试覆盖率和效率。

关于前端技术的学习路径,通常你首先需要掌握最基本的 JavaScript、CSS、JQuery 和 HTML5 等知识,然后再去学习一些主流的前端开发框架,比如 Angular.js、Backbone.js 等。当然现在的 Node.js 的生态圈非常发达,你如果能够掌握 Node.js,那么很多东西实现起来都可以得心应手。我个人推荐从网上下载一些样例代码进行学习,同时学习使用脚手架从无到有去建立自己的前端应用。

2、总结

  • 为了应对技术发展趋势,做好软件产品的测试工作,软件测试工程师需要掌握非常多的非测试专业知识,包括:网站架构、容器技术、云计算技术、DevOps 思维,以及前端开发技术的核心知识以及实践。
  • 对于这类新技术的学习,我强烈推荐你直接阅读官方网站的文档以及代码示例。这种方式,可以让你少走弯路,同时保证所学内容是最新的。
  • 当然,我跟你分享的这些非测试专业知识,只是众多技术的冰山一角,你在实际的测试工作中也会遇到更多的技术,希望你可以举一反三,不断扩充自己的知识面,向着一个优秀测试工程师、架构师努力!

第十一小节  互联网产品的测试策略应该如何设计?

先思考一下为什么我会把互联网产品的测试策略单独拿出来讨论,互联网产品的测试策略和传统软件产品的测试策略到底有哪些不同?

主要是研发流程的不同决定了测试策略的不同。

1、研发流程的不同决定了测试策略的不同

1.1、那就是,互联网产品的“快”

发布周期的巨大差异决定了,传统软件产品的测试策略必然不适用于互联网产品的测试,二者的测试策略必然在测试执行时间和测试执行环境上有巨大差异。

通常情况下,互联网产品要求全回归测试的执行时间不能超过 4 小时。

1.2、那么,如何在保证测试质量和测试覆盖率的前提下,有效缩短测试执行时间呢?

  • 首先,你可以引入测试的并发执行机制,用包含大量测试执行节点的测试执行集群来并发执行测试用例。
  • 测试执行集群,你可以简单理解为是一批专门用来并发执行测试用例的机器。常见的测试执行集群,由一个主节点(Master)和若干个子节点(Node)组成。其中,主节点用来分发测试用例到各个子节点,而各个子节点用来具体执行测试用例。目前,很多互联网企业都建立了自己的测试执行集群。
  • 其次,你必须从测试策略上找到突破口,这也是我今天跟你分享的主题。接下来,我会先简单为你介绍一下传统软件产品的测试策略设计,然后再给你分享互联网产品的测试策略,这样可以通过对传统软件产品测试策略的回顾,加深你对互联网产品测试策略的认识。

2、传统软件产品的测试策略设计

传统软件产品的测试策略,通常采用如图 1 所示的金字塔模型。该金字塔模型是迈克 · 科恩(Mike Cohn)提出的,在很长一段时间内都被认为是测试策略设计的最佳实践,如下图:

《软件测试52讲》学习笔记(四)

2.1、单元测试

金字塔最底部是单元测试,属于白盒测试的范畴,通常由开发工程师自己完成,由于越早发现缺陷其修复成本越低,所以传统软件产品的测试策略提倡对单元测试的高投入,单元测试这一层通常都会做得比较“厚”。

另外,传统软件产品,生命周期都比较长,通常会有多个版本持续发布,为了在后期的版本升级过程中能够尽早发现并快速定位问题,每次 build 过程中都会多次反复执行单元测试,这也从另一个角度反映出单元测试的重要性。

2.2、API 测试

金字塔中间部分是 API 测试,主要针对的是各模块暴露的接口,通常采用灰盒测试方法。灰盒测试方法是介于白盒测试和黑盒测试之间的一种测试技术,其核心思想是利用测试执行的代码覆盖率来指导测试用例的设计。

2.3、GUI 测试

金字塔最上层的是 GUI 测试,也称为端到端(E2E,End-to-end)测试,是最接近软件真实用户使用行为的测试类型。

GUI 测试的优点是,能够实际模拟真实用户的行为,直接验证软件的商业价值;缺点是执行的代价比较大,就算是采用 GUI 自动化测试技术,用例的维护和执行代价依然很大。所以,要尽可能地避免对 GUI 测试的过度依赖。

3、互联网产品的测试策略设计

3.1、GUI 测试

互联网产品的上线周期,决定了 GUI 测试不可能大范围开展。

  • 互联网产品的迭代周期,决定了留给开发 GUI 自动化测试用例的时间非常有限;
  • 互联网产品客户端界面的频繁变化,决定了开展 GUI 自动化测试的效率会非常低,这也是最糟糕的。

        因为敏捷模式下的快速反馈,在下一个迭代(sprint)可能就需要根据反馈来做修改和调整客户端界面,那么刚开发完,甚至是还没开发完的 GUI 自动化测试用例就要跟着一起修改。

       这种频繁地修改,对开发 GUI 自动化测试是非常不利的。因为,刚开发完的自动化用例只跑了一次,甚至是一次还没来得及跑就需要更新了,导致 GUI 自动化测试还不如手工测试的效率高。

由此,互联网产品的 GUI 测试通常采用“手工为主,自动化为辅”的测试策略,手工测试往往利用探索性测试思想,针对新开发或者新修改的界面功能进行测试,而自动化测试的关注点主要放在相对稳定且核心业务的基本功能验证上。所以,GUI 的自动化测试往往只覆盖最核心且直接影响主营业务流程的 E2E 场景。

3.2、API 测试

对于互联网产品来说,把测试重点放在 API 测试上,才是最明智的选择。为什么呢?我给你总结了以下五条原因。

  • API 测试用例的开发与调试效率比 GUI 测试要高得多,而且测试用例的代码实现比较规范,通常就是准备测试数据,发起 request,验证 response 这几个标准步骤;
  • API 测试用例的执行稳定性远远高于 GUI 测试;
  • 单个 API 测试用例的执行时间往往要比 GUI 测试短很多。当有大量 API 测试需要执行时,API 测试可以很方便地以并发的方式执行,所以可以在短时间内完成大批量 API 测试用例的执行;
  • 现在很多互联网产品采用了微服务架构,而对微服务的测试,本质上就是对不同的 Web Service 的测试,也就是 API 测试。在微服务架构下,客户端应用的实现都是基于对后端微服务的调用,如果做好了每个后端服务的测试,你就会对应用的整体质量有充分的信心。所以,互联网产品的 API 测试非常重要;
  • API 接口的改动一般比较少,即使有改动,绝大多数情况下也需要保证后向兼容性(Backward Compatibility)。所谓后向兼容性,最基本的要求就是保证原本的 API 调用方式维持不变。显然,如果调用方式没有发生变化,那么原本的 API 测试用例也就不需要做大的改动,这样用例的可重用性就很高,进而可以保证较高的投入产出比(ROI)。

可见,互联网产品的这些特性决定了,API 测试可以实现良好的投入产出比,因此应该成为互联网产品的测试重点。这也就是为什么互联网产品的测试策略更像是个菱形结构的原因。

如下图所示就是这个菱形的测试策略,遵循“重量级 API 测试,轻量级 GUI 测试,轻量级单元测试”的原则。

《软件测试52讲》学习笔记(四)

3.3、单元测试

了解了“重量级 API 测试”和“轻量级 GUI 测试”,接下来,我就跟你说说为什么是“轻量级单元测试”。

从理论上讲,无论是传统软件产品还是互联网产品,单元测试都是从源头保证软件质量的重要手段,因此都非常重要。但现实是,互联网产品真正能全面开展单元测试,并严格控制代码覆盖率的企业还是凤毛麟角。

追究其主要原因,还是在于互联网产品的“快”。

那么,互联网产品真的可以不用做单元测试么?答案是否定的,只不是这里的单元测试策略要采用“分而治之”的思想。

总结来讲,互联网产品的全面单元测试只会应用在那些相对稳定和最核心的模块和服务上,而应用层或者上层业务服务很少会大规模开展单元测试。

4、总结

传统软件通常采用金字塔模型的测试策略,而现今的互联网产品往往采用菱形模型。菱形模型有以下四个关键点:

  • 以中间层的 API 测试为重点做全面的测试;
  • 轻量级的 GUI 测试,只覆盖最核心直接影响主营业务流程的 E2E 场景;
  • 最上层的 GUI 测试通常利用探索式测试思维,以人工测试的方式发现尽可能多的潜在问题
  • 单元测试采用“分而治之”的思想,只对那些相对稳定并且核心的服务和模块开展全面的单元测试,而应用层或者上层业务只会做少量的单元测试。