核心要点
“设计时为故障做好准备”非常重要,而“测试系统的恢复能力”同样重要;
理解所有在需求中可能未被捕获到的场景。我们需要持续学习和发展技能,以便于降低将应用程序部署到云环境所带来的风险;
使用云原生 QA 宪章来帮助我们思考在生产环境可能出现的场景;
要抵御住自动化所有事情的冲动,专注健壮的自动化并借助云原生 QA 宪章来发挥你的优势。
要关注需求中非功能性行为的问题和挑战。
敏捷团队以及广泛采用的 scrum 流程已经开始打破开发人员和测试人员之间原有的壁垒。在敏捷团队中,质量保证(Quality Assurance,QA)的角色要比以往测试人员涵盖的范围更广。随着不断向团队灌输“质量”的理念,并帮助和推动团队应对每件事所面临的挑战,QA 的范围正在变得无所不包。在现代的软件开发团队中,当谈到测试策略、方式和过程的时候,首先想到的可能是自动化,但很重要的一点是,我们不应该忘记 QA 角色的核心价值。
随着云计算的诞生和云原生计算基金会(Cloud Native Computing Foundation,CNCF)的成立,团队已经从运行大规模分布式系统方面学习到了一些经验。在现实世界中,客户都在期望 24x7 服务,商业领域开始认识到所有的业务都是软件业务,随之而来的则是高风险和高回报。
随着敏捷和云计算的出现,团队中每个角色都有了更广泛的工作范围。全栈开发人员的招聘广告并不鲜见,但是在 QA 方面,我们依然处在测试开发、自动化测试人员、手工测试人员、测试人员、有时甚至全面 QA 中的某个阶段。也许过不了多久,我们就会看到全栈 QA 的招聘广告了。
不管是开发人员(主动地)还是消费者(被动地)都在为 100%正常运行的系统而努力,五个 9 的目标依然在我的潜意识中呐喊,但是在我们生活的世界中,消费者希望得到的是 24x7x365 的服务。
我回忆起 10 年前,当时优步和免触支付(contactless payment)还没有成为主流之前,我的一个旧互联网银行账户服务遇到了中断,这导致我无法在周六晚上的高峰时间段提取现金。当时,我还参与软件开发的工作,这样的服务中断在一定程度上来说是在预料之中的。但是如今,不管是社交平台、在线电子商务站点还是银行应用,消费者都期望他们所使用的服务能够没有中断、持续地提供服务。
考虑到这一点,云生态系统的出现和广泛采用为现代的 QA 带来了新的挑战。所以,我们该如何解决下面这个问题呢:
“在云原生软件业务中,QA 意味着什么呢?”
为了解决该领域的问题,我们首先需要理解敏捷中的 QA 角色以及它对云原生意味着什么。
敏捷中的质量保证
在敏捷团队中,我们期望 QA(以及所有的其他团队成员)完成如下工作内容:
质疑和挑战任何事情(直言不讳地!)
分析需求/用户故事
在敏捷仪式中扮演重要角色
当然,还要进行测试。
这些期望可能需要团队中的所有成员掌握相应的技术,但是作为团队质量的主要驱动力,QA 拥有这些技能是至关重要的。
在分析需求时,我们可以质疑验收标准的有效性,讨论设计、测试方法并关注 MVP(最小可行产品,Minimum Viable Product)。但是,在云原生应用程序中捕获非功能性需求(NFR)并不是一个简单的过程,而且清晰地表达各种场景可能是不现实的。
云生态系统允许应用的开发人员在不必依赖基础设置可用性的前提下,自由满足可用性的需求。开发人员被告知“设计时为故障做好准备”。为了成为云原生环境中的 QA,需要更广泛地理解这些针对故障场景的设计是如何发挥作用的。也许 QA 对“设计时为故障做好准备”的响应应该是“测试系统的恢复能力”。
云原生
为了识别成为云原生 QA 的策略,我们首先需要理解云原生(Cloud Native)这个术语。按照最简单的形式,我们可以将其理解为运行在云中并经过特殊设计的应用,但是这对我们没有什么的助益。云原生计算基金会(Cloud Native Computing Foundation,简称CNCF)是这样描述云原生的:
云原生技术能够让组织在现代的、动态的环境中构建和运行具备可扩展性的应用,这样的环境包括公有、私有和混合云。容器、服务网格(service meshes)、微服务、不可变的基础设施以及声明式的 API 都是这种方式的例证。
这些技术能够实现松耦合的系统,并保证它们有弹性、可管理和可观察。结合健壮的自动化,它们能够让工程师以最小的工作量频繁且可预测地进行影响较大的变更。
云原生计算基金会试图通过培育和维护一个开源的、供应商中立的项目生态系统以推动这种模式的采用。我们将最先进的模式大众化,使每个人都可以使用这些创新。https://www.cncf.io/about/faq/
如果抽取一下 CNCF 中的核心元素,我们可以将云原生 QA 的关注领域聚焦到如下几个方面:
重点关注领域
可扩展性(Scalable)
动态环境(Dynamic Environment)
弹性(Resilient)
可管理(Manageable)
可观察(Observable)
健壮的自动化(Robust Automation)
频繁且可预测的高影响变更
云原生 QA 宪章
我们仔细看一下这七个重点领域,并探讨它们对 QA 意味着什么,或者将范围扩大一下,探讨它们对整个开发团队意味着什么。
可扩展
以往,开发人员会将扩展性问题留给基础设施和运维工程师,他们会重新配置负载平衡器或提供额外的硬件。在云原生应用程序中,这种预期已经不复存在了。也许这是一个架构和设计方面的工作,但是谁能比好奇的 QA 提供更好的评审呢。
服务是如何扩展的?
它是否使用了缓存?
在请求无状态的情况下,这些缓存是如何跨服务运行的?
当已有的实例不再需要时,将会发生什么呢?
在改进的过程中,会遇到扩展性相关的挑战和问题。在云原生应用中,失败是难以避免的事情,我们需要接受这样的现状。
动态环境
软件可能会在数据中心运行,但它可以与云提供商的软件即服务(Software as a Service,SaaS)产品集成,我们需要使用内部网络以满足系统的要求。有些应用程序甚至可能跨云提供商部署,我们如何处理由此带来的延迟问题?
思考一下特性是如何部署的,系统的关键分布式元素都有哪些。
在特性依赖的角度考虑可用性。
如果某个特性出现了故障,它该如何进行恢复?
有弹性
从设计的角度来说,我们经常讨论需要构建一个有弹性的系统。从 QA 的角度来看,如果弹性不是验收标准或 DoD(完成定义,definition of done)的直接组成部分,我们该如何验证弹性。经验丰富的团队可能能够形成一个云原生 DoD,或者围绕该宪章形成一套验收标准。
Kubernetes 可以滚动重启,但是我们该如何优雅地关闭和释放客户端线程?
在节点超载的时候,流量该如何路由?
系统是否能够优雅降级?
如果遗留系统不可用的话,我们是否依然能够响应用户的请求?
可管理
尽管可管理是一个主观性的术语,从 QA 的角度来看,更是如此,但是我们可以将其视为一个可以提出问题的机会。如果我们将“可管理”定义为系统能够在多大程度上适应变更,作为对部署、配置、开发、测试和负载的响应方式,那么云环境的一大优势是,可以由其他人承担通用软件和基础设施可管理性的成本。
所以始终问一下:
它是否有必要由我们来进行构建?
构建它会给我们带来什么价值?
开发人员和架构师不可避免地想要尝试一些新技术,但是 QA 要帮助团队保证质量,需要记住我们是给云厂商付费的,这是因为在管理软件和基础设施方面,他们应该比我们做得更好一些。
可观察性
对于给定的特性,我们该如何确保它在底层平台中的可观察性呢。
测试运维方面的日志。12因素日志并不一定会提供具备可观察性的系统。请求是如何协调的?如果是系统是事件驱动或事件溯源的,捕获到的数据能够提供很有意义的审计跟踪。
指标方面的需求是否能够捕获?
日志是否进行了归档,是够能够进行搜索?
应用是否能够跟踪?opentracing.io
健壮的自动化
健壮性这个词非常重要,它将我们自身和试图进行 100%自动化的误区区分了开来。在规划自动化的时候,关注有价值的领域,不要试图自动化所有的事情。时间是有限的,自动化所有的事情是不可能的,也是没有价值的,所以聚焦有价值的特性并确保测试包是健壮的。
关注重点不应该是大量难以维护的、不可靠的回归测试包,它们不会带来可识别的价值,而要关注智能、简洁,并且能够完成如下功能的测试包:
同时验证部署环境
执行选定的一组功能性任务,并基于场景执行反向任务,这样的场景包括上述的扩展性/可靠性。
这种类型的回归测试包会为开发增加持续的价值,随着产品的成熟和自信水平的提升,这种测试可以不断进行扩展和/或收缩。
频繁且可预测的高影响变更
不管你是采用蓝/绿还是采用红/黑 Netflix 部署方式将产品发布生产环境中,这里的关键都在于确保要部署的特性包含到了指定的范围中:
服务依赖是什么?
是否存在破坏性的变更?
通过持续部署实现持续交付。
在部署进行的过程中,如何运行端到端测试?
如果失败的话,如何回滚?
会发生什么样的结果?
当底层平台达到一定的自信水准后,上面所列的有些表述就显得不那么重要了。
测试金字塔
在测试社区中,测试金字塔理论广为传播。它的终极目标是在被测应用(Application Under Test,AUT)的上下文中,创建一个恰当的测试平衡,从而在有限的时间内交付最大的价值。
与之不同的是,在云原生环境中,服务的失败和降级是预料之中的事情,现有的测试金字塔并没有关注云原生元素。因此,我提供了一个修正案来解决这种关切。
云原生混沌叠加
混沌工程(Chaos Engineering)是在分布式系统上进行实验的学科,它的目的是帮助我们建立系统在生产环境中应对混乱状况的信心。
在此基础上,从 QA 的角度来看,我们可以将这个原则颠倒过来,也就是在单元级别使用较少的测试集,而在 E2E(端到端)级别进行更广泛的测试,在 E2E 级别聚焦高风险的领域,也就是业务影响更高的领域。
在技术上,可以基于特性级别在更早的阶段介入测试,以便于在添加真实的事件(比如网络状况下降、服务降级)之前就能对产品/特性的基线稳定状态得到信心。在生命周期的早期阶段,我们就可以将混沌工程的一些原则引入进来。
我们经常会遇到这种现象:
在单元测试失败的地方才进行代码重构
所做的一切只是为了让测试通过
编写代码的人早就不在了,系统中这部分的变更会让每个人望而生畏
我们并不理解它是如何运行的
我非常害怕眼睁睁地看着系统在我的面前崩溃
大多数的开发人员都遇到过这种场景,所以 QA 该如何倡导质量的理念,并将测试金字塔作为最佳实践的一部分灌输到开发团队的质量过程之中呢?
探索性测试和混沌工程
开发人员和 QA 在敏捷团队中已经紧密协同工作了,但是有关生产就绪的云原生环境中的思维模式并不常见。将混沌工程的元素添加到测试金字塔底部的阶段中,这样就可以将云原生宪章集成到从头开始开发的特性中了。
我们看一下这些工作在实际中是如何运行的,经验丰富的测试人员一直将探索性测试作为一种测试方法,该方法能够基于已有的知识、启发式的理念和风险领域在有限的时间内挖掘出更有附加值的问题。在敏捷中,这种方式运行地非常好。如果说探索性测试是一种思维模式的话,那么云原生 QA 也需要掌握这种根深蒂固的思维方式。
演绎推理允许测试人员基于过去的结果指导未来的推理过程。随着 QA 不断获得底层平台的经验,云原生应用特定领域的自信可能会比不上已经获取到的自信那么重要了*(这并不是说它完全不需要关注)*。在将云原生思考方式集成到测试技术或测试思维模式时,这是非常棒的。
云原生探索性思维导图
在探讨该系统时,要针对“测试系统的恢复能力”进行实验。
在对某个特性运行探索性会话时,请尝试测试我们在云原生宪章中讨论的领域。这有助于为我们的云原生应用程序生成更有价值、更健壮的自动化套件。
环境
随着将应用部署编排到各种环境的工具的出现,我们现在有机会在这些管道中对云原生测试策略的执行进行自动化。
QA、开发人员和产品所有者协同工作,有助于集中精力交付最大的价值。云原生 QA 宪章和混沌工程原则可以帮助确保生产环境中的高价值特性的可靠性。
非常重要的一点在于,探索性测试(借助混沌工程和云原生技术)的输出要进行分析,如果必要的话,将其集成到自动化回归测试包中。需要记住,并不是所有的事情都需要自动化,我们所需要的是一个健壮、快捷和有价值的测试套件。
金丝雀测试
金丝雀测试(Canary testing)是一种用来在生产环境校验特性的技术。它会在用户不知情的情况下,将特性发布给用户的一个子集,而不是扩展到更广泛的范围中。云原生应用通常会包含边缘路由或 ingress 服务,比如 API 网关,它能够限制用户子集的流量,这样的话会减少某个变更出现问题时的风险。使用这种策略能够提升服务切换时的信心。
总结
我们需要记住很重要的一点,那就是在大型分布式系统中,没有一种技术可以解决所有的测试问题。然而,有一些技术,如探索性混沌、云原生契约和云原生探索思维导图,可以指导我们的探索性测试。这有助于推进有效和健壮的测试,以便于在有限的可用时间中获得价值,从而击败竞争对手抢占市场。
QA 通常被认为是下一个测试环境的守门人,并根据测试周期中出现的 bug 数量进行测评。我们必须改变这种思维模式。首先,我们要记住,好的 QA 可以通过及早发现错误来避免一些严重的潜在威胁。
保持好奇心,使用宪章来辅助细化用户故事,形成事情完成的定义(Definition of Done),并帮助进行探索性测试。
我们正处于云原生的学习之旅中,对其进行探索、报道,并从中学习。
关于作者
Greg Simons 是一位具备十多年经验的软件咨询师,担任过各种软件和架构角色。Greg 于 2005 年毕业于威尔士的 Aberystwyth 大学,获得计算机科学一级荣誉学位。Greg 主要使用 Java 和 Spring 技术栈,最近扩展到基于 Node.js 的 Serverless 部署。过去两年,他一直在金融领域担任平台架构师。Greg 热衷于为云环境中的高可用系统构建和设计有弹性的软件。他喜欢谈论和撰写关于云原生的所有内容,你可以在 Twitter 上通过 @gregsimons84 联系到他。
查看英文原文:The Cloud Native QA
评论