开发者测试—程序开发人员测试指南(1)

发表于:2018-5-03 09:48

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

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

  第1章 开发者测试
  在跨职能团队里工作会加大软件专业人员的责任。这种团队中,很少人会有这种不切实际的奢望--每天只要执行范围变动不大的任务而不必去关心作为一个整体的团队会发布什么。这种跨职能模式会使日常工作更具活力和有趣,但这也要求每个人准备去承担在过去可能属于不同角色所做的工作。对于开发人员来说,这体现在要对自己所写的代码的质量负起责任,而不是期望有人会去测试它。这绝不是什么新的东西,但是频繁的交付,也许频繁到一天几次,则有必要强调力求在缺陷被引入之前就能消除缺陷的开发实践。因为质量不是靠测试的,而是靠构建出来的,并成为测试领域的一部分。
  1.1  开发者测试
  开发人员总是测试他们的软件。想象一下初学者写他们的第一个"Hello, World"程序,毫无疑问,他们将执行它来验证那段被世界上成千上万的程序员重复输出的永恒的话(见图1-1)。
  图1.1  在怀旧环境下运行的一个众所周知的程序的随机测试
  开发人员不需要成为测试专家,一些类型的测试需要特定的技能;或者与被测试的软件保持一定的距离,以减轻软件开发者可能受到任何主观偏见(作为作者而引入的)的影响,这就是为什么测试是一个相对独立的专业领域。
  在进一步进入该领域之前,让我们暂停一会来明确"开发人员"的真实含义。在一些团队里,尤其是那些实施敏捷开发(增量迭代)的团队,开发团队里所有的成员都是开发人员,他们精通编码、测试、接口设计或架构(Sutherland & Schwaber 2013),在这本书中"开发人员"指的是其首要职责是编写程序的人。
  无论所有的测试都是在团队内完成的,还是由外部人员来做的,开发者的输出应该是可以工作的软件,而不仅仅是一些编译的东西,为了满足团队制定的质量标准,或者为了避免将低质量的软件交付给最后测试的人,开发者必须确保他们代码的正确性,为了做到这一点,他们必须以一种使验证成为可能(译者注:可测试性)的方法来编写他们的代码,下面我们就正式进入开发人员测试!
  1.2  开发人员测试活动
  一个开发人员每天做多少测试相关的工作呢?在下一章我们会看到给"测试"下定义并不完全是没有价值,但在这一章,为了简化问题,我们不那么正式定义它,并且忽略某些方面。目前,让我们把"测试"看作是确保软件正确性和质量的一项活动,当从这个角度来看,相当多的活动都可以被视为是"开发者测试(developer testing)"。
  1.2.1  单元测试
  开发人员写单元测试。这是验证他们写的代码中所含假设的最简单、最快、最一致的方式。要么他们在写代码之前编写单元测试,以驱动(程序)设计,要么他们在写代码之后编写单元测试,以验证程序确实按所期望那样正常工作。在第一种情况下,测试和验证的表现可能没有在第二种那么明显,尽管如此,单元测试应该是百分之百由开发人员负责。
  1.2.2  集成测试
  在这一章中,"集成测试"的确切定义仍然有点模糊(它会在第3章 "测试术语" 中被定义)。目前,让我们承认有这样一些测试,它们比单元测试更复杂,也更适合开发人员来写。这样的测试需要更复杂的设置,并且执行得相当慢。手动地运行它们很困难,因为它们与源代码和实现细节耦合起来,并且因为数量很大,所以手动运行也很不切实际。
  1.2.3  维护
  一个系统的生命周期的大部分时间是进行软件维护,这并不是行业中严格保守的秘密,而是一个众所周知的事实。一旦一个软件被推出成为产品,它就进入维护阶段。维护分为下列两种类型:
  ·  维护一个正在开发的系统--该系统已经在生产运行中,然而新的功能正在被添加进去。
  不断地往整个系统的代码中添加新功能会变得非常棘手。部分代码库被重构,并且其他代码库被扩展,最终的结果将有希望在某种程度上得到验证,但不是大多数的功能一被实现就能这样。在此期间,代码必须是足够的完整来让整个团队去处理它。开发人员的工作是维护和保证软件在集体所有的(混乱)情况下还能处在工作状态中。
  ·  修补和错误修复--该系统已经稳定运行相当长的一段时间,需要相对较少的干预,但是一旦偶尔弹出一个严重缺陷,就需要修复缺陷。
  小心地引入变更,其变更的范围仅仅局限于解决缺陷而让其他地方不受影响。一个成熟的修复错误的技能是先不急于修复某个缺陷,因为有缺陷存在,先写一个测试程序,测试会不通过;在没有错误的情况下,这一测试会通过。一旦测试到位,错误就会被确定下来,如果修复是正确的,测试就会通过。这个测试现在在代码库里,并且保证修复的存在和正确性。这也是开发人员的工作。
  这两种类型的维护都要求我们谨记所写代码应具备可测试性。相反--代码把各种尝试转换为"猜谜游戏和噩梦"的混合物,这样的代码被称为遗留代码。Michael Feathers是《有效地处理遗留代码(Working Effectively with Legacy Code)》一书的作者,他把"遗留代码"定义为没有经过测试的代码。
  一个处理遗留代码的安全方式是在做出任何改变之前,回溯追加测试,以牵制遗留代码的行为。这种测试被称为表征测试(Feathers 2004)。这样做是费时的,有时还很困难,并不总是一个令人兴奋的活动,但是可取的方式是在做出任何改变之前仔细阅读代码,并且确保其他代码没有被破坏。
  添加缺少的测试并做出实际的修改就落到了开发人员的头上。
  1.2.4  持续集成
  持续集成(Continuous Integration,Cl)是频繁集成的实践,并且始终保持主版本构建的稳定性(Duvall, Matyas &Gloversion 2007)。这种实践有两个方面--技术方面和社会方面。技术层面的持续集成由实现一个自动稳定的构建所需的过程和基础设施组成:
  (1)在向版本控制系统提交任何代码之前,开发人员获取最新版本的代码,将其与本地修改的代码进行合并,并在他自己的机器上运行测试集--单元测试被付诸实践。
  (2)如果所有的测试都通过,开发人员把新的代码提交到版本控制系统。构建服务器能捕获代码的变化,获取最新版本的代码、编译它,并运行其单元测试。这就是基本(bare-bones)的CI,被一些刚起步的团队采用。
  (3)长时间运行的测试和代码分析(如代码覆盖率、违反编程规范)要么在夜间运行,要么在每次CI 服务器负载允许的情况下运行。
  社会纬度是关于一丝不苟地执行CI实践--通过在提交之前在本地运行测试、通过频繁提交,除此之外,还能应对失效的构建,在提交任何工作之前快速修复它们。这需要自律和一个朝着共同方向努力的团队。把这些事情做好往往比建立基础架构和自动化更难。
  那么,开发人员从什么地方开始测试?他们在提交代码之前写测试和运行测试,并且修复构建时出现的问题。但通常情况下,他们会设置CI服务器,尤其是当他们需要运行单元测试和集成测试的时候。
  1.2.5  自动化测试
  在许多情况下,自动化测试是开发人员应该做的事。只有时间和想象力限制了什么样的工作可以实现自动化测试的范围,如测试数据和环境的生成、脚本执行或者自动检查。
  验收测试驱动开发也是一个很好的例子,因为它归根结底是要写一个对非技术的用户可读的、由开发人员使用的、由专门的框架来执行的测试。究竟谁应该写测试,使用什么样的格式和工具,不同的人有不同的观点。然而,从开发人员的角度来看,这些差异可以被认为是次要的,最后,提供执行测试的基础平台构建是开发人员的工作,在很多情况下,这个代码量相当大,对于上述的其他自动化活动也是一样。
  1.3  开发人员通常不做什么
  在前面的章节的示例中没有提及可用性测试、安全性测试和性能测试。这些都是重要的测试类型,但它们往往需要不同于开发人员的技能。实际上,我们可以期望专业的开发人员去阅读一些用户界面设计指南,去了解文件遍历漏洞SQL注入、缓冲区溢出和跨站点脚本等方面知识,并且去熟悉最流行的算法的时间复杂度。
  然后就是探索式测试,这可以由在跨职能团队里的开发人员来执行。我的经验是,探索式测试效果很好,特别当他们不在自己已经实现的功能上运行探索式会话(译者注:这里的session翻译为测试人员不断质疑系统的"会话"更好,时间大约为60~120分钟),而是专注于帮助他们的同事(译者注:针对其他同事所开发的功能进行探索式测试,效果会更好,体现了测试需要相对的独立性,如前面所说,降低主观偏见的影响)时。这是一件好事,只是非本书所讨论的内容。
  最后,还有一些活动,与著名(臭名昭著)的"测试人员思维"相关。可以肯定地说,开发人员通常不会花费他们的工作时间去创建那些非常令人讨厌的(nasty)测试用例。如果在团队里有专业的测试人员,他们既不会专注于故障注入、创造竞争条件(race conditions),也不会用其他的方式弄乱他们软件的状态。
  令人讨厌的测试用例
  什么是令人难受的测试用例呢?就是尝试设计一些(特别是从一个开发人员的角度来看)异常的或不可预知的测试用例。在我的经历里,测试I/O相关的错误就是一个很好的例子。开发人员多久能碰到一次要写入一个文件或者将一些数据存储在数据库中但磁盘已被写满的情况?目前,很多编程语言都能很出色地处理这种问题。极度缺乏测试的应用程序往往对这样例外处理得相当的差。在许多情况下,他们会显示一个纯技术性的错误信息给用户,比如说"I/O错误"。但是难道用户就不想要一个更具体的错误提示信息吗?比如一个提示系统磁盘已满的信息。测试人员就肯定会在发布应用程序之前测试这些,并很可能会创建一个小的磁盘分区来装满它,只留下几个字节的可用空间,观察系统会如何反应。在某些情况下,这将是一个关键的测试。
  其他情况下,相同的测试人员将会进行判断并优先进行其他的测试,特别是如果磁盘"I/O"不重要或者系统的运行空间几乎没有风险。总之,测试人员可能是最有资格做这样的测试,并做出权衡。
  由于两种专业的复杂性, 开发工作什么时候变成测试工作是不可能确切说清楚的,这完全依赖于环境和应用领域、复杂性、法律法规或团队组成等因素。然而,有些情况下,很明确的是开发人员的验证所获得的收益是逐步减少的。

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

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号