不喜欢TDD(尝试这个行为驱动的开发示例)

本文概述

  • 为什么测试会减少?
  • 什么是BDD?
  • BDD与TDD有何不同?
  • 行为驱动的开发是关于协作和沟通的
  • 行为驱动的开发是关于共享工件的
  • 总结
测试。它通常留到最后一分钟, 然后由于时间不足, 预算过多或其他原因而削减。
管理层想知道为什么开发者不能仅仅” 在第一时间就做到” , 而当不同的利益相关者描述系统的不同部分时, 开发者(特别是在大型系统上)可以措手不及, 比如盲人描述一个系统的故事。象。
但是, 不可避免的是, 每个项目的第一步都是讨论要构建的软件或功能的行为。客户或业务人员会见开发团队中的某人, 并说明他们想要的东西。
有时, 这些交互以敏捷用户故事的形式出现。有时, 它们以设计文档的形式出现, 例如Chris Fox去年的博客文章。它们还可以作为流程图或Keynote中的模型出现, 甚至可以匆忙拨打电话。
仅从这些通信中, 开发人员负责构建一个” 正常工作” 的系统。
仅从这些通信中, 开发人员就有责任构建一个” 可行” 的系统。对于在大型系统之外工作的自由职业者而言, 这尤其困难。
为什么测试会减少? 这里有一个明显的差距:如果企业主从一开始就设想了系统的行为, 那么为什么要测试这些行为实际上是有效的, 却往往会被削减呢?
答案可能是非常简单的:测试通常不被视为共享资本。他们不会被认为对项目具有价值, 因为” 它们只是为工程师提供的” , 或者类似地, 它们为单个部门或一群人提供价值。
我们如何对共享的资本, 系统行为列表进行测试?通过不仅包含测试驱动的开发(TDD), 而且包含行为驱动的开发(BDD)。
什么是BDD? 行为驱动的开发应专注于代码正在实现的业务行为:代码背后的” 为什么” 。它支持以团队为中心(尤其是跨职能)的工作流程。
当开发人员与敏捷产品所有者或业务分析师坐在一起, 并在纯文本编辑器中编写待处理的规范(由开发人员稍后填写)时, 我已经看到敏捷BDD确实能很好地工作:
  1. 业务人员指定他们想要在系统中看到的行为。
  2. 开发人员根据他们对系统的理解提出问题, 同时还从开发角度写下所需的其他行为。
理想情况下, 双方都可以参考当前系统行为的列表, 以查看此新功能是否会破坏现有功能。
不喜欢TDD(尝试这个行为驱动的开发示例)

文章图片
我发现这个简单的动作给了我足够的约束, 使我像开发人员一样思考:” 鉴于我必须实施这些测试, 这如何将我/每个人约束到我可以在代码中实现的规范中?” ?由于它们尚在等待规范中, 因此可以在广泛的协作中快速简便地编写。
这种协作方法使我可以专注于该功能为最终用户提供的功能, 而让业务人员就位则使我无法谈论行为, 而不是实现。这突出显示了BDD与TDD的差异。
让我们看一个行为驱动开发的例子
场景:你是负责Rails中实施的公司会计系统的团队的开发人员。有一天, 一个业务人员要求你实施提醒系统, 以提醒客户其待处理的发票。因为你正在按照该教学法练习BDD; (相对于TDD), 你与该业务人员坐下并开始定义行为。
你打开文本编辑器, 并开始为业务用户想要的行为创建暂挂规范:
it "adds a reminder date when an invoice is created" it "sends an email to the invoice's account's primary contact after the reminder date has passed" it "marks that the user has read the email in the invoice"

对开发过程中行为的关注使测试对于验证你正在构建正确的功能(而不仅仅是代码正确)的有用。请注意, 措词是使用业务语言, 而不是系统的内部实现语言。你不会看到或不关心发票属于一个帐户, 因为开发团队以外的人都不会在乎。
措词是用业务语言而不是系统的内部实现语言。你不会看到或不在乎发票属于一个帐户, 因为开发团队之外的人都不会在乎。
一些开发人员喜欢现场编写测试用例, 在系统中调用方法, 设置期望, 例如:
it "adds a reminder date when an invoice is created"do current_invoice = create :invoice current_invoice.reminder_date.should == 20.days.from_now end

测试套件将失败, 因为我们尚未编写代码来设置hinter_date。
与不合格的规格相反 我了解开发人员编写了失败的规范, 但是与我一起工作的业务人员对我来说从来没有用过。错误的业务人员要么会被细节分散注意力, 要么会获得新知识, 然后尝试对开发人员所了解的事情进行微观管理(正确的数据库设计, 代码重用)。
以我的经验, 对一个特定行为撰写多于一行的概述会使业务人员感到厌烦。他们会认为这是对时间的浪费, 或者急于描述下一个行为。
BDD与TDD有何不同? 让我们以一种测试驱动的开发方法来研究这种不同的方式, 并写出挂起的测试:
it "after_create an Invoice sets a reminder date to be creation + 20 business days"it "Account#primary_payment_contact returns the current payment contact or the client project manager"it "InvoiceChecker#mailer finds invoices that are overdue and sends the email"

这些测试很有用, 但仅对一组人有用:工程师。 BDD可用于与跨职能产品团队的每个成员进行沟通。
在BDD思维方式下, 你当然可以通过使用未决行为来进行测试优先开发。首先, 编写测试;然后运行它(红色);然后使其工作(绿色);然后正确处理(重构)。
BDD社区中的许多工作都使测试中的断言检查看起来像英语。这是定型的RSpec测试:
a = 42 a.should == 42

这种格式使事情在以后更容易阅读。但是请记住, 这不是我们在这里所做的, 目的是尽可能快地消除行为, 并执行” 每个规范一个经过测试的行为” 的原则。理想情况下, 待定的规范标题应告诉你要测试的内容。
BDD与验证结果的理想方法无关;这是关于在团队中的所有成员之间共享预期的行为。
行为驱动的开发是关于协作和沟通的 让我们回到我们的场景:使用公司会计系统。
你将与业务人员一起浏览该项目的功能, 并通过其内部分析系统(对象内部如何组装), 然后从外部分析系统。
你考虑了一些条件, 并询问业务分析师在以下情况下会发生什么:
* What's the default reminder date going to be? How many days before the invoice due date? * Are those business days or just calendar days? * What happens if there's not a primary contact associated with the account?

然后你会得到答案。重要的是, 业务人员必须了解你不是要在他们的宠物创意上打孔, 也不是过于腐。
通过这种方式, 行为驱动开发是一种工具, 可以帮助协作并启动两个部门之间的对话。这也是阐明所需功能范围并从开发团队获得更好估算的一种方法。也许你意识到, 无法从给定的时间点计算10个工作日;这是你需要实施的另一项单独功能。
开发人员将具有开发人员考虑因素(“ 你所说的” 一天” 到底是什么意思?” ), 而商务人士将具有自己的考虑因素(“ 请不要在这里使用过期的术语, 这意味着有所不同” )。让一个小组或另一个小组去尝试自己编写这些业务逻辑行为测试(Cucumber的承诺)可以削减双方的宝贵投入。
当Agile Client不在房间里时, 它也是一个很好的替代品:将他们的愿望记录在纸上, 并结合开发人员对你所构建内容的分析(和翻译)。
设计文件
srcmini博客的较早帖子Chris Fox谈到了设计文档, 尤其是在项目开始时。对业务行为的理解和提取从对系统有些了解的项目开始, 到需要数十个程序员年才能完成并且具有成百上千个行为规范的项目为止。
克里斯的文章还提到了元素在屏幕上的行为, 这是我经常与设计师发生分歧的领域:” 此按钮在变暗时看起来像什么” 或” 在11个屏幕上看起来如何” , 因为此页面显然是为24英寸屏幕设计的吗?” 与业务人员的这种来回交流可以发现项目的图形资产或页面布局中的空白。
在非常大的跨职能团队中, 有很多团队成员有自己的关注点:设计人员, 开发人员, 可能是运营人员, 数据库管理员, 也许是质量检查人员(是的, TDD和BDD中每个人都有地方!), 每个人有自己的疑虑和问题。 BDD可以比测试驱动的开发更能推动这种协作。来自” 当数据对于此表而言太大时会发生什么?” 到” 嗯, 那将是一个昂贵的查询, 我们希望以某种方式将其缓存” 到” 等等, 用户应该看到所有这些机密信息吗?” , 可能不仅仅是开发人员, 而且对这个新功能有疑问的业务分析师
行为驱动的开发是关于共享工件的
不喜欢TDD(尝试这个行为驱动的开发示例)

文章图片
什么是共享工件?
我喜欢将软件工程中的” 工件” 视为描述项目或项目团队的潜在物理事物, 并且可以在六个月后找到。好的人工制品可以解释事物为何如此。
好的人工制品可以解释事物为何如此。工件是保存在存储库或共享空间中的某些源代码, 或者是票证系统中的票证。
走廊上的对话不是人工产物。白板图纸也没有。白板图纸已变成大型的长篇文档或设计文档, 这些都是工件。会议纪要也是文物。
工件是一些保存在存储库或共享空间中的源代码, 以及票证系统中的票证, 或者内部Wiki上的注释, 甚至是持久聊天记录。
在我看来, 共享的工件是最好的工件。它们不仅显示出某种事物为何如此, 而且还表明了它为什么存在于应用程序中。
你如何在BDD中使用它们?
行为应该是团队的共同产物-测试不应该只是程序员的工作!最好有一个整个团队都可以轻松查看当前规范的系统(也许部署系统还可以提取行为列表并将其保存到站点或Wiki的私有区域中), 但是你也可以在每个短跑。
游戏的名称是” 帮助开发人员创建我们需要的规格, 以更快地交付业务价值, 部门间协作以及做出更好的估算” 。
在公司范围内对系统功能的理解也是一种资本形式。这是代码的” 方式” 的” 原因” 。
总结 我们如何解决交付给客户的越野车软件的问题?通过确保测试不被视为” 只有开发人员在乎” 的东西。
【不喜欢TDD(尝试这个行为驱动的开发示例)】描述和理解系统的需求具有超出代码正确性的众多好处:建立部门间对话并确保满足所有利益相关者的关注(而不仅仅是拥有大量花哨头衔的利益相关者)。从一开始就使用行为驱动的开发来理解这些需求, 并测试整个团队关心的外部业务行为, 这是确保高质量项目的好方法。

    推荐阅读