NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

你的应用就绪了吗?

  • 2014-02-07
  • 本文字数:4149 字

    阅读完需:约 14 分钟

问题很简单,却很难回答。

我们通常会按时间交付软件,在截止时间之前努力完成所有开发和测试工作。我们会优先完成那些自己觉得重要的部分,当应用达到确定的质量标准后,就准备上线了。因为发布的内容可能不会尽善尽美,所以我们总是假设将来还有一些版本。甚至我们交付软件时,都不能辨别应用的就绪状态。我们总是依赖于测试人员给我们答复,但为了产品的收益和质量,我们应该让所有人都参到这个过程中。

在本文中,我们将会围绕发布一个工作应用程序讨论当前流行的几种不同测试方法。然而,这些不是你“常规”的测试工作!我们强调质量不能变成最后打补丁。我们的目标是在整个编程过程中打造并保证质量。

测试简史

现在我们的开发项目中有作为职能小组的测试人员,在那之前软件的用法都很简单,所以只让开发人员确保软件可以工作就够了。但是随着项目越来越大,应用变得更加复杂,发布截止日期也更紧了。因为程序员永远都不够用,而且会越来越紧张,所以就要求他们在很短的时间内开发更多的特性。在巨大的“质量洼地”里长满了虫子。我们急需杀虫剂。

测试人员将成为那些杀虫剂。随着职责流转,测试人员将成为守护者,捕捉从构建中遗留下来的虫子。很不幸地是,这个主意没有成功。应用太复杂了,有太多场景需要测试人员充分覆盖。即使引入了自动化,测试花费的时间也不可能低于原型开发的时间。而虫子仍然在那儿,满地都是。

在最近几年里,特别是随着敏捷方法的发展,测试已经在生态系统中有了彻底转变,自始至终我们都不可能离开测试了。另外,从安装版软件,到客户端 / 服务器端,再到云和移动应用的转变,已经决定了应用是否“做好市场准备”会面临更多的挑战。

如今的测试非常复杂

通常,我们认为测试是达成可交付软件的重要环节。但是你仔细想想看,在开发过程中测试无处不在,它肯定不是一个“周期”或者一项“任务”,而是散布在整个产品研发组的一套技能。

一个简单的例子可以很好地解释为什么测试不仅仅像最初定义的那样只是检查工件。假设你确定了如下需求:记录应用中的 3 处错误将锁定用户。这看上去非常直白,但当你开始认真研究时,你会发现很多问题:什么是错误?锁定后会触发什么?这些“隐性”的需求可能并不明确,而需要我们理解上下文中的要素。

我们来进一步说明:如果我们捕获的所有需求都是一成不变的,那么我们如何完成所有测试?你不能在生产环境中测试,所以要在一些预生产环境的服务器中做功能测试。你需要运行集成测试用例,运行场景脚本,验证实际的运行情况,然后它自己再完成清理工作。我们也可以在单元测试层面测试这些用例,但需要模拟数据库和环境调用。

那只是一个简单的需求,在测试人员实际操作之前就已经都完成了。

反馈回路

在敏捷时代 V 模型已经过时了, 但即使在今天仍用它来表述一些基本的概念,说明过程中的每个步骤有哪些验证操作的测试点。

如今我们叫它们“反馈回路”,可以用戴明的 PDCA 循环描述。

我们在敏捷开发中尝试把这些循环周期变得尽可能简洁。瀑布项目的问题是循环周期太长,反馈周期超过一周、一月甚至一年。然而,每个开发人员隔几分钟都要编译自己的代码,他们很清楚:循环周期越短越好。

在不同的情况下我们可以灵活使用这些循环。然而,当我们想要验证一个工作特性时,就遇到了这样的现实。

较短的反馈循环不会“恰好发生”。我们需要把它们应用到实践中。这给时断时续的“即时编译”带来了可能性,因为:

  • 我们有促成这种可能性的工具。高效的编译器大大加快了反馈速度。
  • 我们清楚反馈工作的意义,为此创建了一个专门用于反馈的系统。我们的程序每隔几分钟就会自己去点击“编译”按钮。甚至如果我们在适当的时间内没获得反馈都觉得不太正常了。

当代码编译的速度相当快的时候这是成立的。如果高效的、轻量级的编译器需要几个小时的编译时间就太慢了。这样我们就无法经常执行它,无法得到反馈,只好从头再来。

通过隔离快速反馈

为了获得较短的反馈回路,我们需要削减关注点。例如,为了避免过长的编译周期,我们可以执行增量编译。我们可以只编译变更的部分,而不必等着完整的编译都结束。这其实是风险的权衡:我们为了反馈速度牺牲了反馈质量。虽然系统在完整编译完之后可能会有不同的表现,但是我们假定这些差异并不大。我们在这种假定的前提下去缩短反馈回路。

以隔离系统和过程的某些部分去获得更快的反馈并不是新的观点,在开发过程中出现了很多这样的想法。即使我们可能不使用这些术语(比如在增量编译这个案例中),但是会用于其他的场景下,比如需要快速验证反馈的时候。

验证和隔离

构建正确的应用:构建错误的产品是最大的浪费。我们要在产品开发初期识别正确的需求,甚至可以先做一个原型系统。产品人员使用各种各样的工具(包括实体模型、图纸和原型)去收集需求和反馈意见,验证还在正确的轨道上继续开发,或者要做战略调整(精益创业术语),改变方向,再次收集反馈,最终回到正轨。

注意这种验证与原先的 V 模型需求验证的差异:我们验证是否构建了客户所需的,而不是验证是否正确构建了规定的需求。在初期,我们不需要实际的应用。以后,我们要不停地收集数据。为了持续地开发和完善,我们需要在实际系统中不断地收集应用数据。

功能性单元测试:这是非常典型的隔离性应用案例,因为如果不具备好的隔离性,很多功能都无法快速测试。不管你使用模拟框架、依赖注入容器还是简单的 TDD 和抽象依赖,归根到底都是把测试从环境中隔离出来。单元测试背后的思想是得到快速反馈,所以显然要拥有可以达成这一目标的工具。

如果你考虑单元测试的流程和它所要达成的目标,你就会发现以隔离性为基础构建软件(例如,SOLID 原则)还有其他好处。我们通常把应用的易维护性看作开发团队增加新特性、修复缺陷或修改设计的能力。如果流程中没有快速的测试反馈机制,那么就会面临风险,白白浪费时间。

功能性集成测试:我们做单元测试的时候会导致与增量构建相似的后果:快速反馈的代价就是增加了系统内流程未充分测试的内在风险。集成测试更像完整的构建:我们在获得高质量反馈的同时也要承受“慢”的代价。我们要花时间准备和执行测试,但它们却能让我们最终以更好的视角去了解系统的性能。

我们有时会试图隔离系统的各个方面去缩减这些时间。所以我们可能要模拟浏览器操作,在 UI 层下运行包括数据库代码的流程。或者,我们可能要在图形用户界面(GUI)中执行不涉及数据库的测试;这需要在反馈质量和速度之间作出取舍。

通讯测试:虽然它是一种特定的集成测试,但通讯测试需要特别拿出来讨论,在此我分享一下我的个人经历:十年前,我们团队正在开发一个用于大量硬件软件接口。这个接口要实现基于 TCP 和 UDP 的通讯。但我们开发的时候硬件还没有到位。当然,我们可以等,但是我们不想因此影响进度。我们确定了消息信息和结构、通讯连接和恢复以及错误处理机制,以构建网络模拟器。在那时它还不是自动化的,只是一个展示接收信息的应用,能够针对请求向我们的软件发送返回消息。后来我们增加了一些用于不同场景的自动化处理,比如信号交换。

有了这个模拟器不仅加快了我们的开发和集成速度,它还向我们反馈了通讯组件的开发完成情况,记录了出现的故障,还能当作参照工具来用。

非功能性需求:很久以前,我们只关心质量。然而今天,我们取得了长足的进步,现在需要关心更多东西,包括:

  • 可扩展性:某些框架的设计目的是扩展和自定义。我们通常为用户提供一些 API,用户可以用这些 API 扩展一些我们原来没有想到的功能。当我们确认系统扩展性的时候,创建了用于扩展的模拟器(有时是真正的组件)去检验它的运行情况。
  • 安全性:有时我们的应用有硬性的安全需求,但是大多数情况下安全性是后期添加的要求,它的难易程度完全取决于每个独立的开发人员。我们可以使用静态代码分析工具或请外界专家对应用做威胁评估。但很不幸地是,只有在与产品类似的环境下才能执行完整的安全扫描。除非那种像过渡场景下的环境,但这也意味着还要针对现场服务器做最终的测试。
  • _ 可扩展性和性能:_ 特别是服务器端的应用,我们需要评估的应用的能力不仅是大量请求的响应,还包括未来请求增长时的执行情况。我们使用工具对系统做压力测试,根据工具的反馈结果了解系统的性能。此外,我们希望提前预知,为此我们会在一个孤立的系统中执行测试,而不是在会影响到实际用户的服务器上。
  • _ 可用性和可靠性:_ 系统性能很重要,但可用性是庞大用户的基础。此外,我们还要评估应用经受宕机以及其恢复的能力。我们使用压力工具在独立的服务器上执行测试用例,应用针对这些用例反馈行为表现。
  • _ 可移植性:_ 在移动领域,我们习惯在多种设备上测试我们的应用。每种设备会有不同的操作系统、内存、资源和性能。随着每种新设备的上市,在多种设备上完成测试已经成了一种挑战。我们为了在短时间内保持有效性一直都在不懈地努力,现在正致力于模拟器的方向。我们用软件模拟器代替物理设备,确认应用能够在多种设备上正常运行。

用户体验:最后这一点对于人类用户来说是无可替代的。这需要测试人员的参与。测试人员站在用户的角度发出用户的声音,回答像这样的问题:这有益吗?我能达成目标吗?这就是我们测试的实际系统。

当剩下的测试都自动化了,那么手工探索性测试就是最后的难题了。测试人员批准之后它就可以上线了。

总结

产品研发复杂且具有风险。我们要确保构建了适当的特性、确保功能的正确性,并为灾难和成功做好准备。理解早期反馈工作和越来越多可以做的测试,在交付之前回答我们的问题:是的,它已经就绪。

关于作者

Gil Zilberfeld从小就从事软件工作。他做过 20 年的商业软件开发,具有丰富的软件方法和实践经验。Gil 是 Typemock 的产品经理,在敏捷公司内从事敏捷团队的部分工作,研发敏捷开发工具。他推动单元测试和其他设计实践、可落地的敏捷方法,以及某些非常酷的工具。除了每月的在线网络研讨会,Gil 还在国际演讨会上做单元测试、TDD、以及敏捷实践和通讯的演讲。他在业余时间里还打打僵尸,呵呵,开个玩笑。Gil 的博客包括不同的敏捷专题:流程、通讯和单元测试。

查看英文原文: Is Your Application Ready?


感谢侯伯薇对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-02-07 06:541897

评论

发布
暂无评论
发现更多内容

离散性行业介绍及与MES系统的好处

万界星空科技

MES系统 产品资讯

室内LED全彩显示屏P3和P5有什么区别

Dylan

LED 全彩LED显示屏 led显示屏厂家 户内led显示屏

当红语言模型利器:深度解析向量数据库技术及其应用

Baihai IDP

人工智能 AI 向量数据库 白海科技 大语言模型

采用Excel作为可视化设计器的开源规则引擎 NopRule

canonical

低代码 规则引擎 可视化开发 可逆计算 Nop平台

基于 Flink CDC 高效构建入湖通道

Apache Flink

大数据 flink 实时计算

ARTS week4

Z.

ARTS 打卡计划 #ARTS 左耳朵耗子

WiFi Scanner for Mac(Wifi无线网络扫描管理软件) v3.1完美激活版

mac

苹果mac Windows软件 wifi scanner 无线网络扫描管理软件

人工智能新范式,创新驱动生产力

百度开发者中心

#人工智能 ChatGPT 文心一言

Serialbox for Mac(序列号查询工具) v2023.09永久激活版

mac

windows 苹果mac Serialbox 序列号查询软件

这一次,大模型颠覆广告行业!

Openlab_cosmoplat

人工智能 大模型

DevSecOps 中的漏洞管理(下)

禅道项目管理

DevOps 漏洞

数据通信网络之OSPFv3基础

timerring

数据通信网络

极光笔记 | 推送服务数据中心选择:合规性与传输效率的双重考量

极光JIGUANG

文本智能的未来发展方向

百度开发者中心

AIGC #人工智能 生成式AI 文心一言

3天上手Ascend C编程丨通过Ascend C编程范式实现一个算子实例

华为云开发者联盟

人工智能 开发 华为云 华为云开发者联盟 企业号9月PK榜

冰火两重天——GTLC有感

IT民工大叔

个人成长 GTLC 技术领导力

“价值交付课程”11月4-5日 · CSPO认证周末班【提前报名特惠】CST导师亲授

ShineScrum捷行

玖章算术叶正盛将揭示为什么PostgreSQL不如MySQL流行?|3306π

NineData

数据库 postgresql 开源 叶正盛 NineData

谷沁清益生菌清口含片,守护口腔健康的第一道防线

联营汇聚

火山引擎DataLeap的数据血缘用例与设计概述

字节跳动数据平台

大数据 企业号9月PK榜

构建值得信赖的生成式AI应用

百度开发者中心

#人工智能 生成式AI 文心一言

对线面试官 - 绝无仅有真实线上问题排查面试题突击篇

派大星

Java 面试题

当今怎么还沿用水晶头呢?

小齐写代码

S0001-大环境介绍

远观钱途

9月23-24日·上海线下·CSM认证周末班【提前报名特惠】“全球金牌课程”CST导师亲授

ShineScrum捷行

领域驱动设计(DDD):DDD落地问题和一些解决方法

付威

Spring 条件注解没生效?咋回事

江南一点雨

Java spring

你的应用就绪了吗?_研发效能_Gil Zilberfeld_InfoQ精选文章