介绍
在软件开发中,关于测试存在许多神话。软件测试的本质是什么?“单元测试”类的软件测试的目的是什么?我们应该将其视为“单元测试”还是“集成测试”?为什么我们真的需要有人将“TDD”中的“T”替换为“B”,然后开始一场关于“T”和新“B”之间差异的哲学讨论?验收测试只是“BDD”的另一个替代或替换吗?在接下来的内容中,我将以一种非正统的思维方式展示我对这些问题的看法。那么,让我们从……开始。
当然,“测试”和“测试”总体上。
一切都是关于“测试”和“测试”
是的,所有的争论都在于测试软件,无论是测试前还是测试后,或者是手动测试还是自动化测试。根据《牛津语言词典》,测试可以是名词或动词:
作为名词,它的意思是:
一种旨在确定某物的质量、性能或可靠性的程序,特别是在其被广泛使用之前。
作为动词,它的意思是:
采取措施检查(某物)的质量、性能或可靠性,特别是在将其广泛使用或实践之前。
简而言之,可以将测试视为一个明确的、具体的、清晰的、以结果为导向的、业务相关的(至少在代码方面😉)逐步程序,是由于某物的工作证明而创建的。测试意味着运行这些测试或使用这些测试,以接受或拒绝某物。好吧,有些混乱。让我们举个例子。
假设我们要制作一个茶杯。作为一个用于倒茶的茶杯,它应该有一个耐热水的把手,以防止手部烫伤。
因此,测试的过程可能如下所示:
- 将一些水煮沸至100°C
- 在茶杯中放入茶包
- 倒入水
- 小心操作🙂
- 触摸把手
- 等待20秒
- 看看你的手指
- 它们不应该是热的
如你所见,过程由一系列步骤组成,一个接一个,专注于一件事,具体且可测量、可量化。这对于测试程序至关重要。
测试意味着按照这些步骤进行,最后接受或拒绝被测试的茶杯。
再看看测试。测试专注于被测试茶杯的一个方面,一个属性。它并不是对茶杯整体的工作证明。我的意思是,通过测试并不意味着茶杯被完全接受。通过测试只是表明茶杯对热水或热茶具有耐受性。它作为预期最终产品的一个单元的工作证明。我们需要其他测试来验证预期茶杯产品的其他单元-方面。
单元测试
到目前为止,我们理解了测试的意义和目的,以及测试某物的行为。现在我们可以想象测试(或测试用例)是多么重要。我想再次强调测试的“工作证明”部分。
顾名思义,单元测试就是关于某个单元的测试。我们用“工作”这个词来替换某物。因此,让我们再一次修订定义。简而言之,单元测试意味着测试一个工作单元。
那么,单元是什么意思?这里的单元指的是被视为单一、完整且隔离的系统的一个独立部分。这里没有关于大小的讨论。单元可以是任何大小或任何层级。完整和单一比大小更重要。
“工作”这个词指的是什么?“工作”意味着各个部分应该在业务上是合理的。
因此,单元测试意味着测试被视为单一、完整的产品的一个独立部分。
例子:
- 测试“下订单”
- 测试“取消订单”
- 测试“预订经济舱座位”
- 测试“更改用户的活动地址”
- 测试“定义新的子分类账账户”
- 测试“下订单后发送电子邮件通知”
- 测试“向购物车添加商品”
- 测试“生成采购订单”
- 测试“更新产品库存”
- 测试“检查产品可用性”
- 测试“处理缺货情况”
- 测试“处理产品退货”
- 测试“生成采购订单”
测试驱动开发(TDD)
当我们听到TDD时,首先想到的是一种被称为红绿重构的循环方法。
TDD是一种哲学性的方法,以进化的方式分步骤(实际上是微小步骤)指导软件开发,通过测试来进行。我们知道我们想要编写什么代码。我们编写一个测试,作为我们头脑中关于将要编写内容的文档。测试当然会失败(红色阶段),因为还没有任何代码。然后我们编写足够的代码来通过测试(绿色阶段)。最后,我们重构代码以使其正确(重构阶段)。
TDD的重点不在于测试。它通过一系列微小的步骤以一种逐步演进的方式引导软件。每一步都基于前一步的设计,设计是前一步的产物。在TDD中,我们的设计主要由测试驱动。驱动一切的应该在设计之前。因此,TDD中的测试部分是如此重要。如果测试是我们设计的主要驱动因素,如果我们的设计存在于(生产)代码中,并且驱动因素应该在设计之前,那么测试应该在(生产)代码之前。困惑了吗🙁?再读一遍这一段。明白了吧😉
TDD的局限性和BDD的兴起
TDD有一些潜在的局限性,容易被误用和误解。测试作为设计的主要驱动因素,过于技术化。它不是一个适合让人们聚集在一起的工具。业务人员无法与测试建立联系。TDD的一个潜在问题是,有些人觉得在功能存在之前进行测试是违反直觉的。在现实世界中,我们通常测试已经构建的东西。然而,TDD涉及为尚不存在的功能编写测试,这对某些人来说可能是一个新概念。
为了解决这些挑战,丹·诺斯(Dan North)开发了一种更具协作性的系统规范方法,称为行为驱动设计(BDD)。BDD侧重于定义期望的行为和结果,使用示例来说明系统应如何工作。这种方法强调利益相关者之间的沟通和协作。
通过关注行为而不是技术实现,BDD旨在弥合业务需求与技术开发之间的差距,确保软件满足用户的需求。
BDD通常包括以下阶段:
- 发现:这个阶段涉及收集有关系统需求、目标和约束的信息。利益相关者、开发人员和测试人员合作识别期望的行为和结果。
- 制定:利用发现的信息创建清晰简洁的示例,描述期望的行为。这些示例通常采用“Given-When-Then”格式。
- 自动化:将这些示例自动化为可执行的测试。这有助于确保系统在演变过程中持续满足定义的行为。
- 执行:定期执行自动化测试以验证系统的行为。
- 反馈:分析测试结果并将其用于向开发团队提供反馈。这些反馈可用于识别改进领域并对系统进行必要的更改。
这些阶段是迭代的,意味着它们可以在整个开发过程中根据需要重复,以确保系统持续满足定义的行为。
BDD示例:在线购物车
假设你正在构建一个在线购物车。使用BDD,你将首先与利益相关者合作,了解购物车的期望行为。你可能会识别出关键场景,例如添加产品、移除产品、计算总价和结账。
接下来,你将编写示例,详细描述这些场景。例如,你可能会指定,当用户将产品添加到购物车时,该产品应显示在购物车摘要中。或者,当用户移除产品时,该产品应从购物车中移除。
在线购物车的BDD场景示例
场景1:将产品添加到购物车
- Given:用户已登录并在浏览产品。
- When:用户点击产品的“添加到购物车”按钮。
- Then:产品应被添加到用户的购物车中,并且购物车总额应相应更新。
场景2:从购物车中移除产品
- Given:用户的购物车中有一个产品。
- When:用户点击该产品旁边的“移除”按钮。
- Then:该产品应从购物车中移除,并且购物车总额应相应更新。
场景3:计算总价
- Given:用户的购物车中有多个产品。
- When:用户进行结账。
- Then:购物车中所有产品的总价应正确计算并显示,包括任何适用的税费或折扣。
验收测试
验收测试是一种确保软件在高层次上满足特定需求的测试类型。验收测试是从最终用户的角度编写的。它将系统视为一个黑盒,给定输入作为决策,处理这些输入,并期望基于决策有一个可观察的效果。
假设一个用户决定在亚马逊购买一本书。他们通过将书添加到购物篮来做出决定。之后,他们期望购物篮中有一本书。因此,在这种情况下,为了检查系统是否满足这一需求,我们可以编写如下测试:
如果
- 用户的购物篮是空的
- 用户选择一本书
当
- 用户将其添加到购物篮
然后
- 购物篮中有这本书,并且准备付款
验收测试有时会与BDD混淆。正如前面所说,BDD不仅仅是测试。它是一种敏捷实践。在BDD的自动化阶段,我们编写验收测试。实际上,我们自动化了一些作为探索产物的场景和示例。
总结
本文通过一种非正统的思维方式,探讨了软件测试的本质、单元测试的目的、TDD和BDD的区别,以及验收测试的角色。希望这些内容能帮助你更好地理解软件测试的不同方面及其在开发过程中的重要性。