开发者眼中的可测试性—程序开发人员测试指南(2)

发表于:2018-5-04 09:56

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:朱少民、杨晓慧译    来源:51Testing软件测试网原创

  4.2.4  为什么要注重可测试性
  说到底,可测试的软件是关于金钱和幸福。软件的项目干系人可以快速推出新的功能,通过开发人员获得准确的预估,并可以在晚上睡上安心觉,因为他们对质量有信心。我们作为每天编写代码的开发人员,也希望能够感到有工作成果,并为我们系统的质量感到自豪。我们也希望自己的工作充实;我们不想陷入周而复始的代码修复循环,也不希望自己的工作是重复的和麻木的。不幸的是,如果我们的软件是不可测试的,那么我们就不得不面临这种风险。不可测试的软件迫使我们付出更多和更艰难的工作,而不是更聪明的工作。
  测试是浪费的
  Stephen Vance
  在开发者测试这本书中,或者从"代码级别测试"一书的作者的角度来看,我确实承认,这是一种非常异端的声音。敏捷方法可以帮助我们改进软件,或者说,改进我们知识工作的成果。我非常小心地表达这一点,并强调结果比方法更加重要。如果一些神奇的思维机器能够不需要编程,就能产生了我们想要的软件,这整本书将只是学术而已。如果我们可以不需要软件而达到同样水平的速度和方便,我们所讨论的原则也就无关紧要。从某种意义上说,相对于高级的人类历史,劳动密集型模式是相当原始的。在人类开始衰退之前,我们只能通过不断改进来实现神奇的未来。
  大部分敏捷方法在一定程度都来源于对20世纪末制造业变革的思考。来自于朱兰(Juran)、邓明(Deming)、大野耐一(Ohno),高德拉特(Goldratt)等人的精益生产(Lean)、全面质量管理(Total Quality Management)、准时制生产(Just-In-Time)、约束理论(Theory of Constraints)和丰田生产系统彻底改变了制造业的状态。敏捷方法认可这些见解,并将它们应用到具有内在创造性和可变性的这一(软件)领域。虽然这些原则需要做一些调整,但它们大多数仍然是适用的。
  一个关键的原则是消除浪费。丰田生产系统甚至有三个表示浪费的词:Muda、Mura和Muri。在TIMWOOD术语表中,Mura至少包括7个子分类的浪费。大部分时间,对于测试我们主要聚焦由于缺陷引起的浪费上,但事实上浪费也会发生在资产和过度流程上。
  当我们投资(即编码时间)在一些尚未衍生出价值的产品之时,我们会产生库存浪费(Inventory Waste)。由于测试从来无需交付,所以测试是永恒的库存。测试是没有直接回报的投资,但可以减少间接的缺陷和进行缺陷预防。
  相对于原生的产品代码,我们可能因为在测试脚本开发上过度的关注,也可能导致过度流程浪费。相对于为修正缺陷所花的代码调试时间、由于遗漏的缺陷而返工,以及每次维护不得不重新熟悉代码,对测试的过度关注是值得的。毫无疑问,从代码一开始保持正确是最好的方式。
  以前的方案清楚地表明 ,测试比所要解决的问题更加有益。但这只是意味着测试是我们能做的最好事情,但并不一定意味着我们已经做到最好。归根到底,我们关心的是软件的正确性,而不是测试。我们需要继续寻找更好的方法,以确保我们的软件的正确性。我还没有找到答案,但有一些有趣的候选方案。
  领域特定语言
  特定领域语言(Domain-Specific Languages ,DSL)有些希望。这种语言简化了软件用户的工作,并避免重复创建类似的代码。通过利用高阶词汇表来封装复杂的逻辑,它让我们更加准确地表达关于问题的想法。如果作者保证DSL的所有元素的正确性,那么在软件完成后,所有层级的代码将是正确的。
  然而,好的DSL是非常难写的。可以论证的是,我们所用的每一个API几乎应该是一个好的DSL,但又有多少是呢?创造一个良好的DSL不仅需要花时间了解领域,而且需要尝试该领域中不同的模型,不断地进行交互以优化软件的可用性和实用性。另外,DSL有不同的特征使用模式、不同层次的相关概念、不同层次的用户专业知识,并且有效技术也随时间而变化。
  举例来说,对于Ruby语言的Capybara验收测试框架,通常认为是一个针对该语言而精心设计的DSL。这个DSL有一套动作集合,例如访问(visit)、填充(fill_in)、点击按钮(click_button)和匹配符(matcher),例如包含内容(have_content),它非常适合于静态网页。有了这种能力,它很快被应用到快速演化的基础工具中,如Selenium,但并非一直没有问题。例如,它在处理单页应用程序的动态性和随时间变化的行为时,仍然碰到很多困难。
  形式化方法
  形式化方法听起来不错。它们提供了代码正确性的形式化验证。不幸的是,我们很难将它应用在大规模的软件中。它们需要大量工作,我遇见的大部分程序员都不愿意对付这种严格的数学推理。研究依旧在继续,但是距离我们应用还有距离。
  类型
  以我的观点看,类型(Types)是主流语言和形式化方法间的一座桥梁。通过使用形式化规格的一个子集,类型可以清楚准确地描述最容易出现的不合法的"边界用例(Corner Cases)",以保证正确性。
  其他
  还有其他方法提供了部分的、复杂或麻烦的解决方案。如果你愿意继续尝试,或许你可以找到一些突破口。在找到之前,继续测试吧!
  4.3  可测试性的定义
  可测试性是一种质量属性,类似于其他"某某性",如可靠性、可维护性和可用性等。就像其他质量属性一样,它可以分解成更细粒度的要素(见图4.2)。可观察性和可控制性是可测试性的两个基石。没有它们,也就没有任何正确性可言。接下来描述的其他细粒度要素,是基于我的经验建立的模型,尽管我希望它们的出现不存在意外或有争议。
  当一个程序元素(Program Element)(见"程序元素")是可测试的,意味着可以将其置于一种可知的状态,并且可以在执行动作后进行观察。此外,这意味着这些动作可以在不影响任何其他程序元素,且不受到它们干扰的情况下进行。换句话说,它是让黑盒测试变得有些透明,并在其中添加一些控制点。
 
图4-2  质量属性"可测试性"的分解
  程序元素
  我将不时地使用术语"程序元素"。该术语的含义取决于上下文。有时它是一个函数,有时是一个方法,有时是类,有时是模块,有时是组件,有时是所有这些东西。我使用这个通用术语来避免蹩脚的句子。
  使用通用术语也解决了强调编程范式之间差异的问题。虽然本书倾向于面向对象的代码,但许多技术也适用于过程和函数构造。因此,我可以使用"程序元素",而不在任何地方写"类"和"方法",并且这个词也指代"函数"或"模块",就像带有一串相关函数的C文件一样。
  4.3.1  可观察性
  为了验证对被测试程序元素的任何动作,都会对其产生影响,我们需要能够观察它。如果无法观察某个测试的效果,那么即使这个测试写得再出色,也是一文不值的。观察软件的方式有很多种,可以按照可侵入性程度的高低对可观察性进行分类。
  最显而易见的观察方法就是检查所测的程序元素产生的任何输出。有时输出是一串字符,有时是布满部件(widget)的窗口,有时是网页,有时是芯片引脚上的上升或下降信号。但是,这种观察方法通常并不足够。


相关文章
版权声明:51Testing软件测试网获人民邮电出版社和作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号