当前位置: 首页 > 科技观察

张胖子和单元测试

时间:2023-03-19 16:56:43 科技观察

1。敏捷运动张大庞所在的公司正在掀起一场轰轰烈烈的敏捷运动。似乎一夜之间,scrum、xp、tdd、userstory等敏捷词汇挂在了每个人的嘴边。公司要求每个开发人员都必须掌握单元测试这一非常基本的敏捷实践。为此,公司还专门组织了单元测试培训。张胖子自然不能落后。他以极大的热情参加了培训。他在会上了解了单元测试的好处,学习了JUnit这个简单而强大的测试工具,明白了在执行测试用例之前会调用“Setup”。该方法进行必要的初始化,执行后会调用“teardown”进行清理。培训中还专门提到了如何制作Mock对象,让张胖子印象深刻:原来不存在或难以创建的对象,可以使用Mock工具(EasyMock、jmockit等)“造假”!公司还专门定义了什么是好的单元测试:1.单元测试是“白盒测试”,应该覆盖各个分支流程和异常情况2.单元测试是面向一个单元(“Unit”)的,即java中的一个或几个类单元。3.单元测试一定要跑得快!4.单元测试必须是可重复的。5.单元测试之间不应该有相互依赖,它们应该是独立的。6、单元测试代码和业务代码同等重要,应该一起维护。培训结束,张大胖信心满满:写单元测试小菜一碟!精明的项目经理趁热打铁,不失时机地向大家提出要求:兄弟们,听说隔壁的团队定了一个目标,单元测试的代码覆盖率必须达到70%,我们一定要超越他们,我们的覆盖率一定要达到75%!2.糊涂张大发摩拳擦掌,准备大干一场。他打开Eclipse,开始查看之前写的代码。准备添加所有单元测试用例,构建100%全覆盖的代码,夺得覆盖冠军!但是第一个小模块难住了张大发。看这段代码,action调用service,service调用dao,dao全是sql,简单的增删改查,能测试什么?嗯,为了代码覆盖率,就大胆写吧,按照分层测试的原则,测试action的时候,mock服务,测试服务的时候,把dao给mock。。。不过张大发总觉得哪里不对,他总觉得自己在测试框架,而不是业务代码。当然,张胖子也遇到过一些具有一定业务逻辑的模块,但是这些模块存在严重的依赖性,依赖于其他10多个模块的接口。超过10个mock对象后,依赖被释放。但是mock对象太多了,很难协调成一致的状态来正确执行测试:当接口1处于状态A,接口2处于状态B,接口3处于状态C...当interface10处于状态X时,测试用来正确执行,唉,真是不容易。说到底,这一嘲弄得张胖子头晕目眩。大胖感慨道:敏捷教练讲单元测试的好处,但能用来展示的都是很简单的例子,真正的代码要复杂得多。情况发生在第二天。同组的小李改了业务代码,却忘了修改单元测试代码,导致很多单元测试失败。大面积的醒目红色,让人触目惊心。小李去修改单元测试,却看不懂大胖的测试用例。他不满道:“大胖子,我看你的测试代码比业务代码还复杂,你是怎么写的?”大胖子委屈道:“别说你了,看了那么多模拟物,头都晕了,怎么办?”测试令人筋疲力尽。3、讨论两人去找项目经理投诉,项目经理说:这个问题很多人都在讨论,我们开会讨论吧!项目经理召集了几位有经验的骨干来讨论这个问题。他首先做了一个开场白:“我们目前的单元测试正在如火如荼地进行,我们组做的很好。其他组遇到了“单元测试运行慢”、“单元测试无法重复执行,换台机器”等问题我们团队几乎没有“,单元测试相互依赖”之类的通病。我们遇到的问题主要有两个:1.张大发和小李反映单元测试代码太复杂,难于维护。张大发的mock10多个接口的测试你一定看过。2、大家认为一些很简单的增删改查,没有必要做单元测试。如果单元测试的维护成本越来越高,我担心大家会慢慢放弃。大家一起想办法吧。”老梁说:“我做单元测试很久了,我觉得如果测试代码需要很复杂的Setup才能开始测试,反映出一个问题:我们的业务代码界面设计有问题!”张胖子赞叹道:“老梁真厉害,一下子就看出了问题的本质。本来就想着怎么把测试做好,没想到是业务代码的问题。”老蔡也附和道:“对啊,简单的单元测试谁不会呢?关键是处理现实中的遗留代码。我们的一些模块API设计问题确实是有问题的。看来到了重构的时候,趁着这个东风把一些不好的设计改进了,这样测试肯定会变得容易一些。大胖,小李,重构的过程基本上就是一个重新设计的过程,这是一个很好的学习机会。”大胖说:“我也学习了一些重构,所以就想实践一下。”大家纷纷表示同意,项目经理却尴尬地说:“重构可能要花很多时间,而且可能会引入新的bug,还必须涉及到测试。这样的话会不会影响我们的进度呢?”老梁说:“没有办法啊。如果我们不重构,别说单元测试了,就连我们的代码今天明天都可能打补丁。一个补丁,慢慢腐败,越来越难维护,***没人懂,没人敢改,维护成本天价。胖子说:“没关系,为了学习我愿意加班。”经理赞赏地看了胖子一眼,心里说:“这小子不错,干劲十足,年终考核要靠点儿了。”就这样决定了。”经理说,“大胖子,你去做相关的重构吧。有问题请教老梁和老蔡。“如果不测试,怎么保证正确性?我们的代码覆盖率肯定达不到75%。”胖子说“没必要追求代码覆盖率,否则”老蔡说,“对于这样的代码,我们不应该写单元测试,而是通过自动化的功能测试来覆盖它!”“嗯,我觉得这样是可行的,”功能测试可以由开发写,也可以由测试写。”项目经理说,老梁说:“我同意,还有一个建议,以前我们都是程序员在自己的机器上跑单元测试。该过程被添加到自动化构建中,包括单元测试和功能测试,作为重要的质量保证。4、经过团队一年的努力,张胖子的项目组通过单元测试和功能测试编织了一张密密麻麻的安全网。不管变化多小,回归测试都有测试用例。现在当你需要更改代码时,你比以前更有信心了。更重要的是,对关键核心代码进行了重构,接口API越来越好,代码易于阅读和维护,没有了脏代码的羁绊,新的需求也更容易实现。张胖子感慨:“有了自动化的单元测试,我们确实变得更加敏捷了。”当有人问他如何做单元测试时,张大发说:“我告诉你,关键是如何处理遗留代码。”》【本文为专栏作家“刘欣”原创稿件,转载请通过作者微信获得授权公众号coderising】点此查看该作者更多好文