0%

【Google软件测试之道】像 Google 一样进行软件测试

如果你没有一个在 Google 做测试开发的朋友,那么就看看这本书吧。


更新历史

  • 2022.03.19:开始阅读
  • 2022.03.20:完成初稿

读后感

虽然这本书写于 2013 年,都快差不多十年了,但是其中的思路依然没有过时。当然,随着时间的推移,不同的技术不断涌现,但是对于人的品质的要求是一致的。做一天和尚撞一天钟是没有前途的,只有看见树木也看见森林的人,才能把手上的工作做好,并带领大家一起做好。影响力这个机制是天才般的构想,这使得技术人员需要跳出技术之外,看看技术如何能够影响到他人,这才是一个靠谱团队的目标。

读书笔记

序和前言

  • 一个团队能编写出高质量软件的唯一途径是全体成员共同对质量负责,包括产品经理、开发人员、测试人员等所有人
  • 达到此目标的最好方式是使测试人员有能力将测试变成代码库的一个实际功能
  • 生产力是我们的工作,测试和质量是开发过程里每个人都要承担的工作
  • Google 的测试人员与开发人员同工同酬,奖金、晋升待遇完全一样

Google 软件测试介绍

  • 在 Google,软件测试团队归属于一个被称为“工程生产力”的中心组织部门,这个部门的职责横跨开发测试人员使用工具的研发、产品发布和各种级别的测试,从单元测试到探索性级别的测试
  • 不要招聘太多的测试人员,在 Google,写代码的开发人员也承担了质量的重任。质量从来就不仅仅是一些测试人员的问题
  • 如果在你的职位头衔上有测试的字样,你的任务就是怎样使哪些头衔上没有测试的人可以更好地去测试

质量不等于测试

  • 质量不是测试出来的,但未经测试也不可能开发出有质量的软件
  • 你需要在写完每一段代码后立刻测试这段代码,当完成了更多的代码时就要做更多的测试
  • 测试不是独立隔离的活动,它本身就是开发过程的一部分
  • 质量不等于测试,当你把开发过程和测试放到一起,直到不能区分彼此之后,你就得到了质量
  • you build it, you break it, you fix it
  • 资深管理者一般都来自产品经理或开发经理,而不是来自于测试团队。在产品发布时,有限考虑的是功能是否完整和易用性方面是否足够简单,却很少考虑质量。作为同一个团队,测试总是在为开发让路

爬、走、跑

  • Google 经常在最初的版本里只包含最基本的可用功能,然后在后继的快速迭代的过程中得到内部和外部用户的反馈,而且在每次迭代的过程中都非常注重质量。一个产品在发布给用户使用之前,一般都要经历金丝雀版本、开发版本、测试版本、beta 或正式发布版本
  • 金丝雀版本:每日都要构建的版本
  • 开发版本:一般每周发布一个
  • 测试版本:一般是一个月里的最佳版本

测试类型

  • Google 并没有使用代码测试、集成测试、系统测试这些命名方式,而是使用小型测试、中型测试、大型测试这样的称谓,着重强调测试的范畴规模而非形式
  • 小型测试一般来说都是自动化实现的,用于验证一个单独函数或独立功能模块的代码是否按照预期工作,着重于典型功能性问题、数据损坏、错误条件和 off-by-one 错误等方面的验证
    • 通常在几秒或更短的时间内运行完毕
    • 一般需要使用 mock 和 fake
  • 中型测试通常也是自动化实现的,一般会涉及两个或两个以上,甚至更多模块之间的交互。测试重点在于验证这些“功能近邻区”之间的交互,以及彼此调用时的功能是否正确
  • 大型测试涵盖三个或以上(通常更多)的功能模块,使用真实用户使用场景和实际用户数据,一般可能需要消耗数个小时或更长的时间才能运行完成。大型测试关注的是所有模块的集成,但更倾向于结果驱动,验证软件是否满足追中用户的需求
  • 如果能够自动化,并不需要人脑的经验与直觉来判断,那就应该已自动化的方式实现

软件测试开发工程师

  • 测试先行,在一行代码都没有真正编写前,一个开发人员就会去思考如何测试他即将编写的代码
  • 编写功能代码和编写测试代码在思维方式上有着很大的不同
  • Google 的 SWE 是功能开发人员,SET 是测试开发人员,TE 是用户开发人员(面向用户的任务,包括用例、用户故事、用户场景、探索性测试)
  • 工程师团队的交付物就是即将要发布的代码,代码的组织形式、开发过程、维护是日常的工作重点
  • 共享的基础代码的规则:
    • 必须复用已经存在的公共库,除非在项目特定需求方面有很好的理由
    • 对于公共的共享代码,首先要考虑的是能否可以容易地被找到,并具有良好的可读性
    • 公共代码必须尽可能地被复用且相对独立。与功能的复杂性或设计的巧妙性相比,可复用性带来的价值更大
    • 所有依赖必须明确指出,不可被忽视
    • 如果对共享代码库在某些地方有更好的解决方案,需要重构已有代码,并协助依赖在这个公用代码库智商的应用项目迁移到新的代码库上
    • Google 非常重视代码审核,特别是公共通用模块的代码必须经过审核
    • 在共享代码库里的代码,对测试有更高的要求
  • 测试是应用产品的另外一种功能,而 SET 就是这个功能的负责人
  • 一个产品如果在概念上还没有完全成型时就去关心质量,就是优先级混乱的表现
  • 开发团队在寻求测试帮助的时候,有义务让测试人员相信他们的产品是令人兴奋且充满希望的
  • 审阅设计文档要保持强烈的目的性
    • 完整性:找出文档中残缺不全或一些需要特殊背景知识的地方。通常情况下团队里没人会了解这些知识,特别是对新人而言
    • 正确性:语法、拼写、标点符号
    • 一致性:确保配图和文字描述一致
    • 设计:文档中的一些设计要经过深思熟虑
    • 接口与协议
    • 测试:整套系统的可测试性怎么样
  • 小型测试带来优秀的代码质量、良好的异常处理、优雅的错误报告;大中型测试会带来整体产品质量和数据验证
  • 测试运行要求
    • 每个测试和其他测试之间都是独立的,使它们就能够以任意顺序来执行
    • 测试不做任何数据持久化方面的工作。在测试用例离开测试环境的时候,要保证测试环境的状态与测试用例开始执行之前的状态是一样的

测试认证级别

  • 级别 1
    • 使用测试覆盖率工具
    • 使用持续集成
    • 测试分级为小型、中型、大型
    • 明确标记哪些测试是非确定性的测试
    • 创建冒烟测试集合
  • 级别 2
    • 如果有测试运行结果为红色就不会做发布
    • 在每次代码提交之前都要求通过冒烟测试
    • 各种类型测试的整体增量覆盖率要大于 50%
    • 小型测试的增量覆盖率要大于 10%
    • 每一个功能特性至少有一个与之对应的集成测试用例
  • 级别 3
    • 所有重要的代码变更都要经过测试
    • 小型测试的增量覆盖率要大于 50%
    • 新增的重要功能都要经过集成测试的验证
  • 级别 4
    • 在提交任何新代码之前都会自动运行冒烟测试
    • 冒烟测试必须在 30 分钟内运行完毕
    • 没有不确定性的测试
    • 总体测试覆盖率应该不小于 40%
    • 小型测试的代码覆盖率应该不小于 25%
    • 所有重要的功能都应该被集成测试验证到
  • 级别 5
    • 对每一个重要的缺陷修复都要增加一个测试用例与之对应
    • 积极使用可用的代码分析工具
    • 总体测试覆盖率不低于 60%
    • 小型测试的代码覆盖率应该不小于 40%

SET 的招聘

  • 面试重点在考察候选人如何思索问题的解决方案,而不是解决方案本身的实现有多么高雅
  • 问一个简单的问题,如实现一个函数 acount,统计大写字母 A 出现的次数
    • 候选人不应该一上来就写代码,而是要问问题
    • 普通人的问题
      • 传入字符编码是什么
      • 函数名称是否要驼峰
      • 返回值类型是什么
      • 只有一个 A 时,返回多少;小写 a 是否处理
    • 更好候选人
      • 考虑下扩展性:如返回 64 位整型,因为会涉及海量数据
      • 考虑下复用性:是否需要参数化,使得任何字符都可以被计数
      • 考虑一下安全性:指针都是来自可信任的地址吗
    • 最佳的候选人
      • 考虑扩展性
        • 这个函数会作为 MapReduce 的一部分运行吗
        • 如果这个子程序被每一个 Google 查询所调用,因为外层已经做了验证,是否可以减少空指针检查,这样可以节省上亿次 CPU 调用周期
      • 考虑基于常量的优化
        • 可以假设数据是已经排好顺序的吗
        • 输入的数据是什么结构,能否针对这个结构做优化
      • 考虑安全性
        • 增加一个字符长度的参数,用以保证代码不会运行到指定字符之外的部分
        • 如果指针指向的数据能被其他线程修改,就有潜在的线程安全问题
        • 是否应该用 try/catch 捕获异常
  • 一个优秀的 SET 候选人不应该被告之要去测试代码,这应该是 SET 自然要考虑的地方
  • 普通的 SET 候选人
    • 编写代码过程中很少遇到问题
    • 正确理解指针,没有分配不必要的内存
    • 在代码开始的地方做一些输入验证
    • 理解运行时刻效率
    • 被指出代码中有小的问题时,可以修正它们
    • 代码干净易读
  • 优秀的 SET 候选人
    • 考虑使用 64 位整型 int64 作为计数器变量和返回值的类型,为了以后的兼容性和避免用户使用非常长的字符串而导致溢出
    • 针对分布式的计数计算而准备一些代码
    • 在代码注释中对条件假设和常量做解释说明
    • 在有很多不同的数据输入时可以走查代码,修复所发现的错误
    • 在被要求去做功能测试之前就组做相应的测试
    • 在被要求停止之前,不停地尝试优化方案

测试工程师 TE

  • Google 的 TE 综合了开发者仰慕的技术能力和以用户为中心检查软件质量而对开发者产生一定制约的能力
  • 在研发的早期阶段,功能还在不断变化,最终功能列表和范畴还没有确定,TE 通常没有太多的工作可做
  • TE 需要敏锐的洞察力和领导力,因此很多 Google 的高级测试经理们都来自于 TE
  • 测试计划是最早出现、最先被遗忘的测试产物
  • 做出一个不直接指导测试的计划纯粹是在浪费时间
  • 特质是系统的形容词,代表了产品的品质和特色,是区别于竞争对手的关键,也是人们选择你的产品而不是竞争对手的产品的原因
  • 如果你不能在几分钟内列举出特质,说明你还没有足够理解你的产品,还不能有效地测试它
  • 组件是构成待建系统的模块,是一个软件之所以如此的核心要素和代码块
  • 能力是系统的动词,代表着系统在用户指令之下完成的动作。它们是对输入的响应,对查询的应答以及代表用户完成的活动
  • 能力最重要的一个特点是它的可测试性

测试工程师经理

  • 需要拥有技术能力、领导能力和协调能力。通常都是成长于 Google 的内部团队,而不是空降的
  • 想成为优秀的测试工程经理,第一条建议就是去了解你的产品。对于与被测产品相关的任何使用问题,测试工程经理都应该是专家
  • 工程师需要在团队里发挥影响力,他的工作需要能够影响到整个产品
  • 测试工程经理管理团队,责任团队成员的成长,也就是让他们可以衡量自己发挥的影响力
  • 加入一个新项目的头几个星期,我主要用来倾听而不是发表意见。深入理解团队非常重要,要学习产品的架构,了解团队的最新动态
  • 团队的气氛非常重要,测试团队和开发团队的关系也是一种非常重要的气氛
  • 寻找哪些不会沉迷于系统的复杂性、遇到困难的问题时能够分解为可执行的步骤并能最终解决的人