专栏首页yeedomliu《持续交付:发布可靠软件的系统方法》第4章 测试策略的实现

《持续交付:发布可靠软件的系统方法》第4章 测试策略的实现

第4章 测试策略的实现

4.1 引言

  • 戴明14条之一就是:“停止依赖于大批量检查来保证质量的做法。改进过程,从一开始就将质量内嵌于产品之中。”[9YhQXz]测试是跨职能部门的活动,是整个团队的责任,应该从项目一开始就一直做测试
  • 质量内嵌是指从多个层次(单元、组件和验收)上写自动化测试,并将其作为部署流水线的一部分来执行,即每次应用程序的代码、配置或环境以及运行时所需软件发生变化时,都要执行一次
  • 质量内嵌还意味着,你要不断地改进自动化测试策略
  • 这些测试不仅仅对系统进行功能测试。容量、安全性及其他非功能测试也应尽早建立,也应该为它们写自动化测试套件。这些自动化测试确保不符合需求的问题能尽早暴露,降低其修复成本
  • 如果在项目开始时就遵从适当的纪律准则,这种理想国是完全可以实现的。假如项目已经进行了一段时间,然后你才想实现这样的理想国,就有点儿困难了

4.2 测试的分类

  • Brian Marick提出了如图所示的测试象限,它被广泛地应用于对为了确保交付高质量应用软件而做的各种类型的测试的建模

4.2.1 业务导向且支持开发过程的测试

  • 这一象限的测试通常称作功能测试或验收测试。验收测试确保用户故事的验收条件得到满足。在开发一个用户故事之前,就应该写好验收测试,采取完美的自动化形式。验收测试可以测试系统特性的方方面面,包括其功能(functionality)、容量(capacity)、易用性(usability)、安全性(security)、可变性(modifiability)和可用性(availability)等
  • 时新的自动化功能测试工具,比如 Cucumber、JBehave、Concordion以及Twist,都旨在把测试脚本与实现分离,
  • 等价划分分析(equivalence partitioning analysis)和边界值分析可以帮助你得到尽可能小的用例集合,并保证测试覆盖完整的需求。然而,即便如此,你也要凭直觉来挑选一些最为相关的用例

自动化验收测试

  • 自动化验收测试有很多很有价值的特性
    • 它加快了反馈速度
    • 它减少了测试人员的工作负荷
    • 它让测试人员集中精力做探索性测试和高价值的活动,
    • 这些验收测试也是一组回归测试套件
    • 就像行为驱动开发(BDD)所建议的那样,使用人类可读的测试以及测试套件名,我们就可以从这些测试中自动生成需求说明文档
  • 一般我们将代码覆盖率高于80%的测试视为“全面的”测试,但测试质量也非常重要,单单使用覆盖率这一指标是不够的
  • 作为对自动化验收测试覆盖率比较好的一种评估方法,假设要替换系统中的某一部分(比如持久层,使用另一种实现来替换它)。当你完成替换时,运行了自动化测试,并且测试全部通过了。你有多大自信心,认为系统可以正常运行呢?

4.2.2 技术导向且支持开发过程的测试

  • 有三种测试属于这一分类:单元测试、组件测试和部署测试。单元测试用于单独测试一个特定的代码段。因此,单元测试常常依赖于用测试替身(test double)模拟系统其他部分
  • 然而,为了获得高速度,也有一些代价,即可能会错过应用系统不同部分之间交互时产生的一些缺陷
  • 组件测试用于测试更大的功能集合,因此可能会捕获这类问题

4.2.3 业务导向且评价项目的测试

  • 这类手工测试可以验证我们实际交付给用户的应用软件是否符合其期望
  • 一种非常重要的面向业务且评价项目的测试是演示。在每个迭代结束时敏捷开发团队都向用户演示其开发完成的新功能。在开发过程中,我们也应该尽可能频繁地向客户演示功能,以确保尽早发现对需求规范的错误理解或有问题的需求规范

4.2.4 技术导向且评价项目的测试

  • 验收测试分为两类:功能测试和非功能测试。非功能测试是指除功能之外的系统其他方面的质量,比如容量、可用性、安全性等
  • 很多项目并不把非功能需求放在与功能需求同等重要的地位来对待,而且可能会更糟糕,他们根本不去验证这些非功能需求。虽然用户很少花时间提前对容量和安全性做要求,但一旦他们的信用卡信息被盗,或者网站由于容量问题总是停止运行,他们就会非常生气

4.2.5 测试替身

  • 自动化测试的一个关键是在运行时用一个模拟对象来代替系统中的一部分。这样,应用程序中被测试的那部分与系统其他部分之间的交互可以被严格地掌控,从而更容易确定应用程序中这一特定部分的行为。这样的模拟对象常常就是mock、stub和dummy等
  • 术语“测试替身”(test double),并进一步区分了各种测试替身
    • 哑对象(dummy object)是指那些被传递但不被真正使用的对象。通常这些哑对象只是用于添充参数列表
    • 假对象(fake object)是可以真正使用的实现,但是通常会利用一些捷径,所以不适合在生产环境中使用。一个很好的例子是内存数据库
    • 桩(stub)是在测试中为每个调用提供一个封装好的响应,它通常不会对测试之外的请求进行响应,只用于测试
    • spy是一种可记录一些关于它们如何被调用的信息的桩。这种形式的桩可能是记录它发出去了多少个消息的一个电子邮件服务
    • 模拟对象(mock)是一种在编程时就设定了它预期要接收的调用。如果收到了未预期的调用,它们会抛出异常,并且还会在验证时被检查是否收到了它们所预期的所有调用

4.3 现实中的情况与应对策略

4.3.1 新项目

  • 在这种情况下,最重要的事情就是一开始就要写自动化验收测试。为了能做到这一点,你需要:
    • 选择技术平台和测试工具
    • 建立一个简单的自动化构建
    • 制定遵守INVEST原则[即独立的(Independent)、可协商的(Negotiable)、有价值的(Valuable)、可估计的(Estimable)、小的(Small)且可测试的(Testable)]的用户故事[ddVMFH]及考虑其验收条件
  • 然后就可以严格遵守下面的流程:
    • 客户、分析师和测试人员定义验收条件
    • 测试人员和开发人员一起基于验收条件实现验收测试的自动化
    • 开发人员编码来满足验收条件
    • 只要有自动化测试失败,无论是单元测试、组件测试还是验收测试,开发人员都应该把它定为高优先级并修复它
  • 从一开始,测试人员就应该参与需求写作的过程,并确保在整个系统演进的过程中,他们都能为具有一致性的和可维护的自动化验收测试套件提供支持

4.3.2 项目进行中

  • 引入自动化测试最好的方式是选择应用程序中那些最常见、最重要且高价值的用例为起点。这就需要与客户沟通,以便清楚地识别真正的业务价值是什么,然后使用测试来做回归,以防止功能被破坏

4.3.3 遗留系统

  • 没有自动化测试的系统就是遗留系统。虽然对这个定义还有一些争议,但它的确有用而且简单
  • 通常比较有效的策略是在测试结束后仔细地验证系统的状态。如果时间来得及,你可以再测试一下这个用户故事的Alternate Path。最后,你还可以写更多的验收测试来检查一些异常条件,或防御一些常见的失效模式(failure mode),或防止不良的副作用
  • 切记,只写那些有价值的自动化测试就行。如果只是增加新功能,而不需要修改这个提供支撑的框架代码时,为这部分代码写全面的测试是没有什么价值的

4.3.4 集成测试

  • 我们所说的“集成测试”是指那些确保系统的每个独立部分都能够正确作用于其依赖的那些服务的测试
  • 黑盒测试是价值最高的测试,并要列出外部系统所有可能的响应,并为每个响应写测试。这个模拟的外部系统需要找到某种方式识别你的请求,并回发正确的响应,假如有个请求不能被外部系统所识别,则应该返回一个异常

4.4 流程

  • 最好的解决方案就是在每个迭代开始时,召集所有的项目干系人开个会。假如没有做迭代式开发,那么就在某个用户故事开始开发的前一周召开这样的会议。让客户、分析人员、测试人员坐在一起,找到最高优先级的测试场景
  • 另一种方法是为测试创立一种DSL(Domain-Specific Language,领域专属语言),并用这种DSL来书写验收条件。我们最起码要让客户当场找出最简单的验收测试场景,并覆盖这些场景的Happy Path

管理待修复缺陷列表

  • 达到这一目标的一个方法是,无论什么时候,一旦发现缺陷就立即修复它
  • 还一种处理缺陷的方法,那就是像对待功能特性一样来对待缺陷
  • 我们可以把缺陷分为严重(critical)、阻塞(blocker)、中(medium)和低(low)四个级别

4.5 小结

  • 在很多项目中,测试被认为是一个由一些专职人员负责的独立阶段。可是,只有当测试成为与软件交付相关的每个人的责任,并从项目一开始就被引入并持续进行时,才能产生高质量的软件

  • 《Agile Testing》
  • 《敏捷开发的艺术》
  • 《xUnit Test Patterns》
  • 《Release It!》

工具

  • 自动化功能测试工具,比如 Cucumber、JBehave、Concordion以及Twist

本文分享自微信公众号 - yeedomliu(yeedom_liu),作者:yeedomliu

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 《持续交付:发布可靠软件的系统方法》第3章 持续集成

    yeedomliu
  • 《持续交付:发布可靠软件的系统方法》第5章 部署流水线

    yeedomliu
  • 项目经理思维导图——6 上升空间有限时,该继续努力还是换单位?

    yeedomliu
  • 软件测试计划

    软件测试计划是指导测试过程的纲领性文件,包括产品概述、测试策略、测试方法、测试区域、测试配置、测试周期、测试资源、测试交流、测试风险等内容。

    week
  • 软件测试思想浅谈

    张树臣
  • 10年软件测试工作总结

    张树臣
  • 产品不同测试阶段的测试分析

    软件测试应该贯穿软件产品的整个研发周期,在不同的研发阶段,会有不同的测试方法和手段跟进。进行不同的测试来保障产品的质量。软件测试的分类有很多种,本文章就以一个...

    小老鼠
  • 云端测试和性能测试实战

    随着越来越多的应用程序开始采用云端部署的方式,包括微软 Azure、谷歌云、亚马逊 AWS 或者国内的阿里云、腾讯云等, 怎样确保在本地正常工作的生产代码(Pr...

    小老鼠
  • 功能测试工程师的自动化学习之路

    绝大多数测试同学都是从功能测试做起的,工作忙忙碌碌,每天在各种业务需求学习和点点中度过,过了好多年发现自己还只是一个功能测试工程师。

    吾非同
  • 软件测试初认识(三)

    完成对最小的软件设计单元模块的验证工作。对代码风格和规则、程序设计和结构、业务逻辑等进行静态测试。

    吾非同

扫码关注云+社区

领取腾讯云代金券