《有效的单元测试》一1.3 测试作为设计工具

简介:

本节书摘来自华章出版社《有效的单元测试》一书中的第1章,第1.3节,作者 (芬)Lasse Koskela,更多章节内容可以访问云栖社区“华章计算机”公众号查看

1.3 测试作为设计工具

传统上,程序员编写的自动化测试被看做是质量保证工作,用于在编写的时候验证实现的正确性,以及将来代码进化的时候验证正确性。这就是将测试作为验证工具——你设想一份设计,编写代码实现,编写测试验证实现是否正确。
使用自动化测试作为设计工具将世界颠倒过来了。当你用测试设计代码时,你将典型的“设计,编码,测试”序列变换为“测试,编码,设计”。是的,就是那样。测试先于编码,并以追溯性的设计活动来得出结论。那结论性的设计活动称为重构,序列变为“测试,编码,重构”,如图1.4所示。
image

如果你对这有点耳熟,大概是听说过测试先行编程或测试驱动开发(Test-Driven Development,TDD)。这就是我们所要讨论的,那我们也这么叫吧。

1.3.1 测试驱动开发

TDD,如图1.5所示,是一种很有章法的编程技术,它基于一个简单的想法:在编写出能够证明代码存在的失败测试之前,不写生产代码。这也是它有时被称为测试先行编程的原因。
不止这些。先写测试,会向测试所期望的方向来驱动生产代码的设计。这会带来以下令人满意的后果:
代码变得可用——代码的设计和API适合于你的使用场景。
代码变得精益——生产代码仅仅实现场景所需要的功能。
首先,无论你工作在系统蓝图的哪一部分,无论其他组件、类或接口存在与否,你一定是在为一个具体的场景来设计解决方案。你将该场景翻译为一个可执行的例子,以自动化单元测试的方式。运行测试,看着它失败,你具有了一个使之通过的清晰目标,只编写足够的生产代码——不要多写。

image
    
将场景刻画为可执行的测试代码是一种设计行为。测试代码成为生产代码的调用者,使你在还没写任何代码之前就验证你的设计。用具体例子的形式来表达需求是一种强大的验证工具——我们只能通过将测试作为设计工具才能获取价值。
其次,严格遵循规则,仅仅编写足以使测试通过的代码,你会保持设计简单并适合目的。没有镀金的迹象,因为任何代码都具有测试——场景——来覆盖和保证。代码质量罪魁祸首之一,以及使开发者生产力停滞的主要因素,就是称为偶发复杂性。
偶发复杂性是不必要的复杂性。可以通过替换为简单的设计来避免它,同时仍然满足需求。有时我们喜欢通过产出这种复杂设计来展示自己的精神能力,却使自己都理解不了那些设计。我打赌你也认识到自己的原始本能了。复杂设计会扼杀生产力,偶发复杂性也会事与愿违。
测试指出缺陷或代码中缺失的功能,只写足以使测试通过的代码,严格地向简单设计来重构,这三者的组合极其强大,可以将偶发复杂性消灭在萌芽中。这不是魔法药剂,程序员的设计观念和经验会影响你最终得到的设计。
关于TDD远不止这些——很多书整本都在讲这种方法,包括我自己写的《测试驱动开发的艺术》(Test Driven),以及最近的《测试驱动的面向对象软件开发》(Growing Object-Oriented Software,Guided by Tests,作者Steve Freeman,Nat Pryce)。如果你想要更紧凑的TDD介绍,我推荐你读《测试驱动开发:实战与模式解析》(Test Driven Development:By Example,作者Kent Beck,2004)。
有这么多具体对TDD的介绍,我们这里就长话短说,你可以参考那些书来进行更深入的探索。但我在这里讨论TDD的原因是,它与我们关于优秀测试的主题紧密相关——称为行为驱动开发(Behavior-Driven Development,BDD)的编程风格。

1.3.2 行为驱动开发

你可能听说过BDD,即行为驱动开发。虽然过去的几十年间,人们曾用过测试先行的方式,但20世纪90年代才真正提出测试驱动开发的方法。
大约10年过去了,身在伦敦的顾问Dan North,首先意识到了TDD思想和词汇表中所讲的“测试”会误导人们,然后成功地将测试先行编程推进了一步。Dan将这种风格的TDD命名为行为驱动开发,在他2006年发表于《Better Software》的文章中,他是这样介绍BDD的:
我突然想到人们对TDD的误解几乎总是回到“测试”这个词。
并不是说测试不是TDD的本质——所产生的函数和方法是一种有效确保代码工作的方式。然而,如果函数和方法不能全面地描述系统的行为,那么它们会带给你一种虚假的安全感。
在我处理TDD时,我开始使用“行为”替代“测试”一词,我发现它似乎不仅合适,而且所有的教练(coaching)问题都奇妙地解决了。我现在对TDD的一些问题有了答案。给测试命名变得简单——一句话描述下一个你感兴趣的行为。测试的数量变得毫无意义——你只能在一句话中描述这么多行为。当测试失败,你仅需要重走一下上述流程——要么你引入了一个bug,要么行为改变了,或者测试不再是相关的。
我发现从思考测试到思考行为,这种转换如此深刻,我开始改称TDD为BDD或行为驱动开发。
Dan开始编写和讨论BDD之后,全球软件开发者社区中的其他人也纷纷将想出的各种实例驱动、行为需求导向的想法融入Dan North的BDD中。于是,今天的BDD语境和领域远远超出了代码——最引人注目的是将BDD提升到需求层面,与业务分析和需求行为结合起来。
被BDD实践者证明是有效的一个特殊概念,是利用验收测试进行由外向内的开发。这是《Cucumber:行为驱动开发指南》(The Cucumber Book:Behaviour-Driven Development for Testers and Developers)一书作者Matt Wynne和Aslak Helles?y所描述的:
通过将优秀的TDD实践者的良好习惯正式化,测试驱动开发衍生出了行为驱动开发。优秀的TDD实践者由外向内地思考,他们先编写一个失败的客户验收测试,用于从客户视角描述系统。作为BDD实践者,我们小心地以例子的形式编写验收测试,使任何团队成员都能够理解。我们遵循这个过程,编写例子来从业务干系人那里获得反馈,在动手之前就能了解我们是否在构建正确的东西。
作为这种开发方式的佐证,许多BDD工具和框架如雨后春笋般,纷纷将基础的想法、实践和约定嵌入到软件开发者的工具链中。我们会在第8章见到那些工具。
当我们在本书说到“优秀测试”时,记住Dan的领悟,注意措辞。词汇表很重要。

相关文章
|
10天前
|
测试技术 C语言
网站压力测试工具Siege图文详解
网站压力测试工具Siege图文详解
19 0
|
1月前
|
JavaScript jenkins 测试技术
这10款性能测试工具,收藏起来,测试人的工具箱!
这10款性能测试工具,收藏起来,测试人的工具箱!
|
1月前
|
人工智能 监控 测试技术
利用AI辅助工具提升软件测试效率
【2月更文挑战第17天】 随着科技的不断发展,人工智能(AI)在各个领域的应用越来越广泛。在软件测试领域,AI技术也发挥着重要作用。本文将探讨如何利用AI辅助工具提升软件测试效率,包括自动化测试、智能缺陷识别和预测等方面。通过引入AI技术,软件测试过程将变得更加高效、准确和可靠。
164 1
|
1月前
|
Web App开发 前端开发 测试技术
探索自动化测试工具:Selenium的威力与应用
探索自动化测试工具:Selenium的威力与应用
探索自动化测试工具:Selenium的威力与应用
|
29天前
|
测试技术
现代软件测试中的自动化工具与挑战
传统软件测试面临着越来越复杂的系统架构和不断增长的测试需求,自动化测试工具应运而生。本文将探讨现代软件测试中自动化工具的应用和挑战,深入分析其优势与局限性,为软件测试领域的发展提供思路和启示。
|
11天前
|
Java 测试技术
SpringBoot整合单元测试&&关于SpringBoot单元测试找不到Mapper和Service报java.lang.NullPointerException的错误
SpringBoot整合单元测试&&关于SpringBoot单元测试找不到Mapper和Service报java.lang.NullPointerException的错误
16 0
|
25天前
|
jenkins 测试技术 持续交付
现代软件测试中的自动化工具与挑战
随着软件开发领域的不断发展,自动化测试工具在测试过程中扮演着越来越重要的角色。本文将探讨现代软件测试中自动化工具的应用及面临的挑战,旨在帮助开发人员和测试人员更好地理解和应对自动化测试中的问题。
|
7天前
|
缓存 自动驾驶 测试技术
如何进行有效的Apollo测试:单元测试和集成测试指南
如何进行有效的Apollo测试:单元测试和集成测试指南
36 13
|
10天前
|
测试技术 Linux Apache
网站压力测试工具webbench图文详解
网站压力测试工具webbench图文详解
8 0
|
18天前
|
Java 测试技术 API
软件测试中的自动化工具与策略
软件测试是确保软件质量的重要环节,而自动化测试工具和策略的应用在提高测试效率和准确性方面发挥着重要作用。本文将介绍几种常见的自动化测试工具,并探讨在软件测试中应用自动化测试的最佳实践和策略。