| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 开发测试 -> 单元测试驱动开发之旅 -> 正文阅读 |
|
[开发测试]单元测试驱动开发之旅 |
1.事出必有因????????今天能写下这篇《单元测试驱动开发之旅》,源于近期的工作——会员客户管理中心项目的开发。会员客户管理中心,作为未来运营管理体系中的一个基础支撑系统;解决现有问题,规范会员客户基础数据的使用,提供权威的会员客户数据。 ????????会员客户管理中心,立项之初就已确认“以DDD(领域驱动设计)的思想指导项目开发”这一方针。起初,虽团队成员对DDD知之甚少,但是以DDD思想指导项目开发已是板上钉钉的事,我们所能做的就是啃下DDD这块硬骨头。在翻阅大量的DDD相关资料和书籍时,发现有一词与之形影不离——TDD,就这样一颗有关TDD的种子也在悄无声息地埋下了。 ????????为了实现?“标准动作做标准——DDD更标准落地”这一目标,所以我们在项目实现阶段,搭建了DDD框架、采用了JPA技术,引入了TDD思想。伴随着TDD思想的引入,会客团队的单元测试驱动开发之旅也就这样开启了。 2.溯本求源????????通常提及“TDD"一词时,"UTDD"、"ATDD"、"BDD"等名词也会被提及;正如你所见,它们看起来非常相似——“xDD”。 ????????正是因为这“外表"的相似性,它们在我们眼中就如孪生兄弟一般,总是让人傻傻分不清。再加上,网上文章对它们的定义又是千差万别,很容易把人弄得一头雾水。 ????????所以,在开启单元测试驱动开发之旅前,我们需要做一件事:“理清它们之间的关系”。 2.1.关系图谱 TDD有狭义、广义之分。狭义上,TDD 特指UTDD;广义上,TDD 包括UTDD、ATDD。
????为了消除歧义,此处TDD我们统一采用广义上的说法。关系图谱如下所示: 2.2.三世同堂????????我们可以把 TDD、UTDD、ATDD、BDD几者的关系,理解为三世同堂。
3.姓甚名谁????????UTDD,英文全称:Unit Test Driven Development ,中文全称:单元测试驱动开发;是一种敏捷软件开发的技术,它期望通过单元测试用例来驱动软件代码的实现。 3.1.实施流程????????TDD的实施有一个经典三步曲,不论是UTDD还是ATDD都可以按照这三步来实施:“变红->变绿->重构”。对于UTDD而言,这经典三步曲的具体含义如下: ????????1.变红:编写一个刚好运行失败的单元测试用例。 ????????2.变绿:填充一段刚好通过用例的程序逻辑代码。 ????????3.重构:更整洁的单元测试用例、程序逻辑代码。 ????????但是要实施好UTDD,不能只靠这三个核心步骤,还需要相应的其他辅助步骤以及多方协作,下图分别展示了ATDD、UTDD的步骤和协作的基本全貌。 4.为我所用通过前面的介绍,我们已对UTDD的家族图谱以及基础知识有了一定认识;所以本小节聚焦于UTDD在会员客户管理中心的落地实践。 4.1.实践工具????????“工欲善其事,必先利其器。”在实践UTDD之前,我们需要能让UTDD更好落地的工具。会员客户管理中心的UTDD工具集?= JUnit?+ AssertJ?+Mockito
????????上述UTDD工具集的安装教程、使用教程比较简单,可自行查阅网上资料进行实践。 4.2.实践经验????????“纸上得来终觉浅,绝知此事要躬行”。结合书籍理论、项目实践,对实践TDD系列敏捷开发技术时,有了以下浅薄认识: ????????第一步就是转变思维——测试左移,将测试用例分析、设计和实现,移至编写代码之前。 ???????第二步就是了解和学习测试基础理论,做到能解答“什么是单元测试?”“单元测试测哪些内容、哪些地方值得测试?”、“优秀的单元测试应具备哪些品质?”等系列问题,具体可参考 Right-BICEP 、CORRECT、FIRST原则等内容进行学习。 ????????第三步就是结合项目进行具体实践,因为“说一千道一万,不如亲身实践一遍”。 4.3.实用建议????????下图源于《有效的单元测试》,是作者结合工作总结提炼而成的。我们可以仿照此图,从 测试的执行速度、测试的可阅读性、测试的可维护性、测试的可靠性等几个方面给出具体建议。 4.3.1.测试的执行速度????????首先我们可以尝试执行已有的单元测试,看看具体的执行速度是怎么样的?若执行时间超越秒级计数,那毫无疑问你需要为该单元测试的执行速度提提速。那怎么样能提高测试的执行速度?观察我们所执行的单元测试,不难发现项目在执行单元测试时,需先初始化一些相关依赖项,而正是这些依赖项拖慢了执行速度。所以,我们只需减少或不依赖?相关外部基础设施、组件、spring容器等即可! ????????若能结合领域驱动设计思想,使用领域驱动设计框架,我们只需对领域层进行单元测试即可。补充说明:领域驱动框架的领域层用于存放?领域模型,往往为了保证领域层的纯粹性,而不会直接依赖相关的外部基础设施、组件、spring容器等。 4.3.2.测试的可阅读性????????依据《与代码共同演进的活文档》的观点,我们所编写的单元测试可看做是一份精炼的文档。那么问题就由“怎么让测试具有可阅读性?”变成了“怎么让文档具有可阅读性?”。 ????????个人理解,可阅读性的文档往往是规范化的、结构化的,所以我们可以从规范化、结构化两方面入手提升可阅读性。 ????????规范化:
????????结构化:
4.3.3.测试的可维护性????????若对程序员提问“什么是万恶之源?”,相信绝大多数人都会回答“重复”。简单说,重复是存在多份拷贝或对单一概念的多次表达——这些都是没有必要的重复。 ????????没有必要的重复是不好的,它增加了代码的不透明性,使得散落在各处的代码难以理解。此外,当变更重复项时,每修改一处重复都是而外开销,若遗漏了修改某处会增加出现Bug的机会。 ????????个人理解,单元测试除了分析、设计测试用例外,其余的主要是构造场景数据,紧接着 使用场景数据?验证预期逻辑。而往往就是在构造场景数据时,会出现大量的重复项。 ????????针对以上问题,我们需要引入“数据夹具”这一概念。数据夹具,实际上是为测试准备一系列状态对象的工具类。借助数据夹具,一是可以有效消除重复代码(同时也便于维护),二是能极大调用开发者的情绪(只需传几个关键参数,然后由数据夹具统一返回预期对象)。 4.3.4.测试的可信赖性
4.4.心得体会4.4.1.明显好处降低开发时的思绪负担 ????????在以往软件开发工作中,常会有“思绪万千”?的感觉(不知从哪动手、如何动手);而当采用UTDD后能有效解决这一问题,只需照UTDD的基本流程:变红->变绿->重构,按部就班进行即可。其实这和软件分层架构的思想 如出一辙——“关注点分离”。我们在软件编程的过程中,主要几个关注点:需求、设计、实现。 ????????变红:写一个让程序运行失败的单元测试用例,它是对一个小需求的描述,只需要关心输入输出,这个时候根本不用关心如何实现。(需求) ????????变绿:专注实现当前需求,不关心其他需求,也不管代码质量是多么惨不忍睹。(实现) ????????重构:既不用思考需求,也没有实现的压力,只需要找出代码中的坏味道,借鉴《重构——改善既有代码》中的手法一并消除它们,让代码变成整洁的代码。(设计) 督促写出整洁可用的代码 ????????Kent Beck在《测试驱动开发》一书中,就开宗明义地提出:TDD的所追求的目标是 Clean code that works(代码简洁可用)。Code that works: 代码首先必须可用——单元测试。Clean code: 代码应该尽可能简洁——重构。 ????????在编写单元测试用例之前,你需要进行 需求分析、考虑程序的使用性、可测试性。并且你只能填充刚好让用例通过的程序逻辑代码,从而有效避免了过度设计,软件代码做到了 “可用”。正因你频繁地重构单元测试用例、程序逻辑代码,软件代码做到了 “整洁”。 协助达成质量内建的目标 ????????采用UTDD的第一步是转变思维——测试左移,将测试用例分析、设计和实现,前移至编写代码之前。这是一种极大程度的测试左移,那是不是能极大程度享受测试左移带来的好处?理想情况,你所写的每一行程序逻辑代码,都是为了通过单元测试用例;换而言之,你所写的每一行程序逻辑代码,都通过了单元测试用例。 默默编制一张系统保护网 ????????采用UTDD进行程序实现的同时,无形中也在为软件系统编织一张保护网(单元测试用例)。当有新的变化需求或重构代码时,你可以大刀阔斧地去做,因为有张保护网替你兜底(回归测试)。即使时过境迁,这张保护网依然能有效地保护系统的边界,能避免让你的系统成为“烫手的山芋”。 4.4.2.潜在风险凡事都有两面性,UTDD的引入也是有代价和风险的。
5.结语项目从始至终,我们最核心的诉求是,实现我们的朴素目标——“更好更快地开发出更贴切业务、更稳定、易维护的软件”。项目无论是采用领域驱动设计,还是测试驱动开发,亦或是敏捷实践等方法论,都仅仅只是一种保障手段。所以,我们在项目开发工作中,万万不可一味追寻各种手段,却忘记了初心,最终掉入了本末倒置的陷阱中。 |
|
开发测试 最新文章 |
pytest系列——allure之生成测试报告(Wind |
某大厂软件测试岗一面笔试题+二面问答题面试 |
iperf 学习笔记 |
关于Python中使用selenium八大定位方法 |
【软件测试】为什么提升不了?8年测试总结再 |
软件测试复习 |
PHP笔记-Smarty模板引擎的使用 |
C++Test使用入门 |
【Java】单元测试 |
Net core 3.x 获取客户端地址 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/18 0:29:58- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |