“以终为始的软件开发”的那些事 : Myths and Truths

简介: 作为软件开发研发团队,当从客户那里获得了对软件产品的需求,到研发团队给客户交付了满足预期的产品的中间,怎么才是一个有效的,高效的流程和方法?为了回答这个问题,我们先把目光聚焦到敏捷社区软件开发人员都耳熟能详的模式——ATDD,TDD和BDD——能怎样贡献到“以终为始的软件开发”这个目标。本文就将与你

本文根据中生代技术群分享整理而成,具有多年软件研发经历的刘朋为大家分享ATDD,TDD,BDD的那些事,为大家分享“以终为始的软件开发”经验。


文章正文

我分享的主题是TDD,但是其实涵盖的领域会更宽泛。于君泽在前几期里面分享了“以终为始的架构设计”,其实我的TDD分享并不会仅仅拘泥于TDD,或者说我更想和大家讨论一下“以终为始的软件开发”,这个题目也许更为恰当。


所以,我其实想讨论的是:作为软件开发研发团队,当我们从客户(或者客户代表Product Owner)那里获得了对软件产品的需求,到研发团队给客户交付了满足预期的产品,这中间,怎么才是一个有效的,高效的流程和方法。这是我感兴趣的话题,也是我作为研发经理在日常工作中一直在思考和探索的问题。

为了回答这个问题,我们这次先把目光聚焦,我们先来看看三个敏捷社区软件开发人员都会耳熟能详的模式——ATDD,TDD和BDD——能怎样贡献到“以终为始的软件开发”这个目标。

所以,这次分享的第一部分,我们就谈谈:

第一部分:ATDD,TDD和BDD,各种DD的那些事

要谈这个话题,我们首先得了解这三个DD是什么。在Wiki上,对三者的定义是:

ATDD Acceptance Test-Driven Development (ATDD)  is a development methodology based on communication between the business  customers, the developers, and the testers.
TDD Test-driven  development (TDD)  is a software  development process that relies on the repetition of a very short development  cycle: first the developer writes an (initially failing) automated test case that defines a desired improvement or new  function, then produces the minimum amount of code to pass that test, and  finally refactors the new code to acceptable standards.
BDD In software engineering, behavior-driven  development (BDD) is a software development process that emerged from  test-driven development (TDD).

其实看了这三个Wiki上的定义,我只想说:“然并卵”。说得很玄乎,但是到底什么是ATDD,什么是TDD,什么是BDD,它们的关系和联系是怎样的呢?它们如何协同应用贡献到“以终为始的软件开发”呢?


为了解答这个问题,我们给大家整理了一个30秒弄懂ATDD的定义:

如果翻译成中文,那就是:

【30秒搞懂ATDD】

ATDD (验收测试驱动开发)就是一种让整个研发团队(PO,Dev,Tester)一起协同讨论和澄清验收标准(包含实例);并基于此提炼出一系列具体的验收测试(AT),然后再开展具体的软件开发和编码的实践。

ATDD背后的逻辑:最好的验证一个研发团队是否对客户需求有统一的理解的方法就是对客户如何验收有统一的理解。具体到开发工作中,就是有对DoD有共同的理解。

有人说,嗯,懂了一些了,但是还是不完全懂~没有关系,咱们上图:

                                                                                       图1 ATDD 4D循环


哎呦,这个图不简单了,一下子就把ATDD,TDD和BDD的关系和联系展示出来了。如果我们把这个ATDD Cycle放在Scrum实践中,这个图长这个样:

                                                                                     图2 ATDD Cycle in Scrum

下面,让我们按照ATDD 4D的循环,一个D一个D的来解释一下。

ATDD循环之Discuss

  • 目标

         充分的理解客户需求和客户价值
         充分利用团队成员的不同知识和技能理解需求的不同方面
         让所有团队成员都获得对需求的一致理解

  • 希望解决的问题

         对客户价值理解不正确,后期验收不通过
         开发和测试人员对需求理解不一致

  • 输入

         从用户或者用户代表(PO)来的用户需求(用业务领域的语言描述)

  • 输出

         端到端的用户故事(end-to-end user story)

  • 采用的实践

         六顶思考帽


一点点解释:这第一个D(Discuss),目标就是让所有接下来会参与到软件开发中去满足客户需求的各方利益相关者(Stakeholder),都能够在一开始就对用户想要什么有统一的理解。因此,这个讨论需要客户(或者客户代表),架构师,开发工程师,测试工程师,系统测试工程师,系统集成人员,等等相关各方都能派代表参加。在初期达成的一致将会大大减少后期的扯皮。这在我们Nokia的实践中已经被证明是能够很大程度的减少软件开发中不必要的浪费——代码完成后的需求扯皮。

另一方面,为了达到这个目的,需要有讨论,讨论就要开会。那怎么开这个会,也是非常有讲究。在我们的实践中,我们经过尝试了不同的方法,最终觉得使用“六顶思考帽”的方式是非常有效的方式。(关于什么是”六顶思考帽“,请自行Google之,这里不再赘述)。

在具体的实践中,一个需求讨论和澄清的会议的流程这样的:


蓝色帽子——会议主持人
【第一步·白色帽子】收集关于这个需求的背景,事实和数据,供进一步的讨论。注意,这里不讨论任何怎么做
【第二步·红色帽子】在收集完事实之后,所以参会人员的感受如何,是否觉得已经有重复的事实可以进入下一步的需求澄清讨论
【第三步·绿色帽子】讨论正常场景下,客户需要的是什么。举个例子,如果需求是一个用户名/密码登录界面,那么正常情况下软件需要呈现的功能是什么。
【第四步·黑色帽子】讨论异常场景下,客户的需求意味着什么。继续上面的例子,在异情况下,比如双十一超大访问压力下或者遭受黑客攻击时,登陆模块需要呈现的功能是什么。
【第五步·黄色帽子】决定以上绿色帽子和黑色帽子讨论结果的价值和优先级排序。那在上面的用户名/密码登陆模块例子中,如果对于有限的研发资源和交付时间压力,团队是先专注哪些功能,是正常情况,还是异常场景处理。
【第六步·红色帽子】最后,再询问大家的感受如何,今天的会议是否达到了目的,所有stakeholder都对用户需求是什么达成了一致。

好,说道这里,大家可能要问:那我们如何表达对用于需求的理解呢?如何确认所有人都有了一致的理解呢?那就到了ATDD循环中第二个D(Distill,提炼)。


ATDD循环之Distill

  • 目标

       根据团队对需求的充分讨论,提炼出需求(Feature)的验收标准以及相应的测试点
       验收标准将成为后续验收测试用例和产品代码开发的出发点

  • 希望解决的问题

       验收标准不清晰,不一致,导致后期无法验收并产出用户价值
       避免出现传统测试中的“bug海啸”

  • 输入

       端到端的用户故事(end-to-enduser story)

  • 输出

       利用BDD方式描述的验收标准(AcceptanceCriteria)

  • 采用的实践

       BDD的“Given,When,Then”行为描述语言

说道这里,就不得不说一说BDD。BDD的提出者Dan,是这么描述BDD的:

"BDDis a 2nd generation, outside-in, pull-based, multiple- stakeholder,multiple-scale, high-automation, Agile methodology."‍

“BDD是第二代由外至内的、基于拉动的、多利益相关者的、多尺度的、高度自动化的敏捷方法。”

但是,Dan自己也承认,他都不知道这段话说了什么J然而,我们不得不说,BDD的一个关键,看似微小,的改变就是在描述测试点的时候,用“should”替代了“test”。也就是说,你可能会听到在讨论验收标准的时候,问题是“预期的行为是什么?”,而不是“我应该测什么?”举个例子,下面图中女PO和身边的两位研发团队骨干关于“首单打折”这个用户需求

的讨论完全不在一个频道上,从业务语言,到伪代码,到实际的测试函数。无论用哪一种作为描述验收标准的方式,都无法使所有stakeholder都能理解,并且达成一致。

因此,如果换成BDD三段论Given-When-Then模式,将会是下图这样。可以看到,现在所有人都能够用同样的语言,并且是基于软件应该有怎样预期的外部可观察行为的角度,来统一验收标准。而Given-When-Then也天然可以非常容易的在接下来的步骤中转化为测试用例和指导代码开发。

好,到这里,我们已经有了用BDD的三段论(Given-When-Then)描述的验收标准,而且所有的stakeholder都有了统一的认识。接下来,我们就可以开始软件设计和编码,以及测试了。那就到了:

ATDD循环之Develop


这一步就很简单,研发团队可以使用诸如TDD的模式进行代码开发;同时,测试团队根据验收标准开始准备验收测试(可以是自动化,也可以是手动)。

当代码编写和测试完成之后,那就进入了最后一个环节:演示和验收。


ATDD循环之Demo

  • 目标

       根据Scrum团队实现同意的Definitionof Done (DoD)对本sprint产出的软件进行验收

  • 希望解决的问题

       团队对验收标准不清楚
       团队对验收标准有不同的理解而产生争执
       产出的代码虽然工作,但是没有创造客户价值

  • 输入

       经过了测试的软件

  • 输出

       通过了验收标准的可工作和可以发布给客户的软件

  • 采用的实践

       Acceptance test case作为验收重要指标
       设定对于UT覆盖率,测试自动化率的硬性指标

在这一步中,如果一开始所有的stakeholder都对验收标准达成了一致,那这里的验收就变得非常简单:就是把验收标准拿出来,验证其中每一个Given-When-Then是否都有相应的测试用例覆盖;如果需要,PO还可以挑选若干关键验收标准进行现场演示和验收。

好,说道这里,我们再把ATDD Cycle拿出来,大家现在是不是可以总整体上理解ATDD,TDD和BDD这三者之间的关系和联系。以及它们三者如何有机结合,来完成“以终为始的软件开发”这个目的了呢?



那我们第一次分享就到这里,我们下次来聊一聊:TDD三原则,同时,我们也来尝试着回答这个非常挑战的问题:TDD死了吗?



Q&A


Q: 你们有没有核心人员,或多人流动,导致需要重新和新来人员统一产品定义和验收标准的情况?是如何处理的。
刘朋: 关于人员流动导致需要重新定义产品验收标准的问题,我们之前没有用BDD来描述Test Point之前,也很麻烦,就是需要有transfer的成本,但是现在我们的Grooming输出的都是标准格式,用客户(PO)可以看懂的语言描述的验收标准,其实这个成本就小很多了,因为这些Test Point(验收标准)都是很易懂的
因为如果不“干活”的PO都可以懂起,那就不需要transfer成本了噻,哈哈

Q:如何提高和改善TDD的开发效率,尤其是在项目开发过程中。我有专门为公司的UI开发框架写过自动化测试,测试开发实际花费的精力和时间是很多的,如何提高这种开发效率呢?

刘朋:回答问题一如何提高和改善TDD的开发效率:其实Kent Beck说的TDD不是银弹,所以并不是所有场合都需要TDD或者适合TDD,比如UI,就不适合用TDD的方式开发;但是如果你说Web UI的Test Automation,那就是Acceptance Test的问题,是ATDD的问题了,那就有很多工具,比如Selinimu等等工具来提升自动化测试的效率

Q: 验收测试po要参加吧?还是只参加demo部分?
刘朋: 验收测试,在sprint review上Area Product Owner会作为PO的代表(如果PO不能参加的话),去验收所有的Acceptance Test是否都Pass

Q: 这种以始为终的思想,在推动开发人员思维习惯转变过程中,能否可以分享一些经验和关键点吗?
刘朋:  关于“以终为始”观点的改变,其实ATDD是促使大家观念转变的第一件事情,第二件事情是“逼迫”大家(至少初期是这样),用BDD的方式去描述系统应该怎么工作,应该怎么验收,而不是应该怎么测试;第三件事,是让大家体会TDD的好处,因为TDD其实也是在潜移默化的让大家以终为始的思考

其实TDD不是银弹,但是TDD的思想“以终为始”是银弹

因为一开始代码或者设计得可测试性就很低——因为没有“以终为始”

所以多管齐下,让大家看到这么做的好处:和PO沟通更顺畅了,开发和测试终于有共同的语言来描述验收标准了;代码终于不用后补UT了,可测性提高了,都会鼓励大家继续用“以终为始”的方式思考

刘朋:嗯,其实Kent Beck自己也说,即使TDD有一天死了,但是TDD带来的思维的变化-”以终为始“的思考方式,绝对不会过时:)所以这就是为什么要把ATDD,TDD,BDD放在一起,放在一个整体的图景中去理解的原因。

江湖:以终为始  我喜欢,做设计  做架构何尝不是如此

刘朋:这就理解了君泽的架构也是“以终为始”,都是相通的~

其实我特别同意并不是所有team都需要TDD,或者所有项目都需要TDD,Kent Beck自己也说了Farewell TDD,但是他也说了TDD may die, but long live testing!


分享者简介:

刘朋,诺基亚程度研发中心软件研发经理,从事软件研发8年,做过软件工程教练,敏捷教练,致力于探索大规模软件中高效能团队进化之路。



                                                        中生代技术群微信公众号

                                                da9312524921e637b684eed7bf3249db58f7badc



目录
相关文章
|
Prometheus 监控 Cloud Native
【监控利器Prometheus】——Prometheus+Grafana监控SpringBoot项目JVM信息
Prometheus+Grafana监控SpringBoot项目JVM信息 1. SpringBoot项目配置JVM采集 2. Prometheus配置 3. 配置grafana 4. 扩展-通过JMX Exporter监控JVM信息
【监控利器Prometheus】——Prometheus+Grafana监控SpringBoot项目JVM信息
|
3月前
|
人工智能 JSON 运维
🚀🚀 【MCP + AI】grafana-mcp-analyzer:基于 MCP 的轻量图表分析助手
`grafana-mcp-analyzer` 是一个开源项目,通过 MCP 协议连接 AI 助手与 Grafana,实现智能分析监控数据。只需简单配置,AI 可快速解读图表,提供性能瓶颈、优化建议等专业分析,极大提升运维效率。支持多种数据源(Prometheus、ES 等),适配 ChatGPT、Claude 等模型,部署轻量,操作便捷。从此告别深夜手动排查问题,让 AI 成为你的智能运维专家!项目地址:<https://github.com/SailingCoder/grafana-mcp-analyzer>
452 1
🚀🚀 【MCP + AI】grafana-mcp-analyzer:基于 MCP 的轻量图表分析助手
|
缓存 前端开发 JavaScript
如何快速搭建一个前端框架?
【4月更文挑战第7天】快速搭建前端框架,首先确定技术选型(如React、Vue或Angular),然后创建项目目录结构,安装所需依赖。配置开发环境,编写代码,同时进行调试和测试。优化性能后,部署上线。选择框架时,考虑社区支持、学习曲线、性能、兼容性及文档质量。
586 0
|
11月前
|
网络协议 机器人 C++
KUKA机器人Socket通讯配置方法:技术干货分享
【10月更文挑战第7天】在现代自动化生产线上,KUKA机器人凭借其高效、灵活和精确的特点,成为众多企业的首选。为了实现KUKA机器人与其他设备或系统之间的数据交互,Socket通讯配置显得尤为重要。本文将详细介绍KUKA机器人Socket通讯的配置方法,帮助大家在工作中更好地掌握这一技术。
1348 2
|
缓存 搜索推荐 数据库连接
FastAPI 的插件化也太牛了吧!轻松打造可扩展 Web 应用,让你的开发如虎添翼,快来感受这神奇魅力!
【8月更文挑战第31天】在互联网迅速发展的今天,Web应用需求日益多样化。FastAPI作为一种高效灵活的Python Web框架,通过插件化设计帮助开发者轻松构建可扩展应用。插件化让开发者能够根据需求选择合适模块,如用户认证、支付处理等,而无需大幅改动核心代码。这种方式不仅提高了开发效率,还增强了应用的稳定性和适应性,使FastAPI成为未来Web开发的理想平台。
428 0
|
8月前
|
运维 自然语言处理 供应链
阿里云 × 用友BIP超级版联合发布暨产品分享
本次分享介绍阿里云与用友BIP超级版联合发布的解决方案,旨在帮助企业应对数字化转型中的挑战。主要内容分为三部分:一、市场需求及客户痛点,分析企业数字化转型的六大特征和中大型企业在数智化建设中面临的难题;二、用友BIP超级版on阿里云解决方案,涵盖业务架构、三大核心价值主张(超级领先、超级快、超级省)及智能应用;三、成功客户案例,如洛阳钼业在50天内完成采购供应链领域的数字化部署。该方案助力企业快速实现数字化转型,提升运营效率并降低成本。
190 0
|
机器学习/深度学习 边缘计算 PyTorch
PyTorch 与边缘计算:将深度学习模型部署到嵌入式设备
【8月更文第29天】随着物联网技术的发展,越来越多的数据处理任务开始在边缘设备上执行,以减少网络延迟、降低带宽成本并提高隐私保护水平。PyTorch 是一个广泛使用的深度学习框架,它不仅支持高效的模型训练,还提供了多种工具帮助开发者将模型部署到边缘设备。本文将探讨如何将PyTorch模型高效地部署到嵌入式设备上,并通过一个具体的示例来展示整个流程。
2952 1
|
监控 Linux Shell
Linux命令ionice:优化磁盘I/O优先级
`ionice`是Linux工具,用于调整进程的磁盘I/O优先级,改善系统响应。它设置三种I/O调度类:Idle(低优先级),Best-effort(默认)和Real-time(高优先级)。通过 `-c` 和 `-n` 参数分别设定调度类和优先级。示例:`ionice -c3 -n7 command`(低优先级I/O)和`ionice -c2 -p 1234`(改变PID为1234的进程为Idle类)。使用时注意平衡系统资源,避免干扰其他任务,并结合`iostat`、`iotop`监控性能。
|
关系型数据库 MySQL Docker
Docker从容器中项目如何访问到宿主机MYSQL
Docker从容器中项目如何访问到宿主机MYSQL
3705 0