您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 敏捷开发之测试驱动开发和结对
敏捷开发之测试驱动开发和结对ITBU-技术部徐宗敏2010年3月18日Agent1•敏捷开发概述2•测试和开发之间的问题3•测试驱动开发4•结对5•总结6•Q&A为什么要敏捷?需求经常在变化为什么要敏捷?需求失真为什么要敏捷?kickoff没有足够的时间发布为什么要敏捷?提高产品的质量敏捷开发和传统开发流程的对比敏捷开发“前”的产品开发过程(瀑布模型)敏捷开发和传统开发流程的对比敏捷开发“后”的产品开发过程(迭代模型)敏捷开发的价值观•勇于去创新,勇于去改变,勇于接受改变•对于我们产品、对于我们的开发过程的每一步开发的进度,每一步测试的结果,对任何人而言都是透明的。•不断反馈的过程就是不断建立信心的过程。•PD和开发、测试之间•用户和PD之间•开发和开发之间•PD和用户之间•我们要用最简单的方式做我们的事情,无论是设计、开发实现还是测试简单沟通勇气反馈敏捷开发方法完整团队项目墙每日晨会测试驱动开发敏捷开发方法结对编程(codereview等)持续集成重构迭代总结敏捷开发方法需要全用吗?不需要Agent1•敏捷开发概述2•测试和开发之间的关系3•测试驱动开发4•结对5•总结6•Q&A测试的抱怨1.需求变化2.文档更新不及时3.时间太少4.开发质量低5.可测试性差敏捷对测试挑战敏捷对开发过程带来了曙光敏捷确给测试带来了挑战开发会创建更少的文档,更多的时间关注开发,放在沟通,让用户满意的产品上。敏捷的过程中可能需要每个星期就发一个版本需求和设计有更加频繁的改变测试和开发资源的对比Google1/10Alibaba1/3Microsoft1/1Google的测试文化所有工程师对质量有着同等重要的责任测试的任务不仅是发现bug,更重要的是帮助开发人员一起提高产品质量有效地进行验收测试、持续集成、测试驱动开发、自动化测试、结对。开发在设计的同时就考虑可测试性。重沟通,每周会沟通做了什么功能,存在什么风险以任务而非角色安排工作,共享同样的目标,共享同样的任务。Alibaba的测试情况80%开发人员认为测试就是测试人员的事情测试就是不断的发现bug无建立好的持续集成框架80%的项目无考虑可测试性,部分是提交了测试之后再考虑单元测试覆盖率低有codereview,但无结对今天,我们开发所必须要做的意识到提高产品的质量也是开发的重要责任引用敏捷开发的测试驱动开发和结对,提高产品质量帮助测试人员建立持续集成框架、验收测试的标准可测试性的设计Agent1•敏捷开发概述2•测试和开发之间的关系3•测试驱动开发4•结对5•总结6•Q&A从一句大师的话开始编写单元测试是在进行验证,更是在进行设计。同样,它更是在编写文档。心灵震憾一段时间的学习,让我的内心受到了深深的震撼。我们原来的方法居然如此的笨。以前我面对测试先行这一名字时,最大的疑问就是程序都还没有写出来,测试什么呀!。后来一想,其实这是一个泥瓦匠都明白的道理,却是自己在画地为牢。我们来看看两个不同泥瓦匠是如何工作的。工匠师傅的“测试驱动开发”工匠一:先拉上一根水平线,砌每一块砖时,都与这根水平线进行比较,使得每一块砖都保持水平。工匠二:先将一排砖都砌完,然后拉上一根水平线,看看哪些砖有问题,再进行调整。这个就是线你会选择哪种工作方法呢?有可能你会骂工匠二笨吧!这样多浪费时间呀!然而我们自己想想,我们平时在编写程序的时候又是怎么做的呢?我们就是按工匠二的方法在干活的呀!甚至有时候比工匠二还笨,是整面墙都砌完了,直接进行集成测试,经常让整面的墙倒塌。看到这里,你还觉得自己的方法高明吗?我们的问题时间少产品质量要求高变化多我们的问题每一个程序员都知道应该为自己的代码编写测试程序,但却很少这样做。当有人问为什么的时候,最常听到的回答就是:我们的开发工作太紧张了但这样却导致了一个恶性循环,越是没空编写测试程序,代码的效率与质量越差,花在找Bug、解决Bug的时间也越来越多,实际效率大大降低。由于效率降低了,因此时间更紧张,压力更大。你想想,为什么不拉上一根水平线呢?难道,我们不能够将后面浪费的时间花在单元测试上,使得我们的程序一开始就更加健壮,更加易于修改吗?测试驱动开发的精髓将测试方案设计工作提前,在编写代码之前先做这一项工作;从测试的角度来验证设计,推导设计;将测试方案当作行为的准绳,有效地利用其检验代码编写的每一步,实时验证其正确性,实现软件开发过程的小步快走。WhatisTDD?TestDrivenDevelopment(测试驱动开发)测试先行。持续重构。测试驱动开发是一种在极限编程(XP)中处于核心地位的技术。WhyTDD?确保每个方法都是可用的且已被测试过确保及时发现出现问题的模块添加或修改代码更容易频繁地运行测试迭代式递增开发不断重构以改善设计WhyTDD?TDD还能改善和验证设计:以客户端的视角编写测试为客户端提供了示例代码更注重接口的设计为了使测试容易,需要实现松散耦合更少的Debug时间HowtodoTDD?1、写一个空方法。2、写一个测试程序(单元测试用例)。3、让程序编译通过。4、运行测试程序,发现不能运行。(红条)5、让测试程序可以运行。(绿条)6、消除重复设计,优化设计结构。(绿条)7、重构确定业务1、用户可以选择付费月份为1、2、3个月2、用户选择1个月最多可用1个红包3、用户选择2个月最多可用2个红包4、用户选择3个月最多可用3个红包1、写一个空方法publicclassCouponManagerImpl{/***根据选择充值月数和拥有的最大红包数,取得可用红包数*@parammonths充值月数*@paramtotalCoups拥有的最大红包数*@return可用红包数*/publicintgetNumOfCoupsCanUse(intmonths,inttotalCoups){//TODO完成该方法return0;}}2、写一个测试程序publicclassCouponManagerImplTestextendsTestCase{publicvoidtestGetNumOfCoupsCanUse(){CouponManagerImplcm=newCouponManagerImpl();assertEquals(0,cm.getNumOfCoupsCanUse(1,0));assertEquals(1,cm.getNumOfCoupsCanUse(1,1));assertEquals(1,cm.getNumOfCoupsCanUse(1,5));assertEquals(2,cm.getNumOfCoupsCanUse(2,5));assertEquals(3,cm.getNumOfCoupsCanUse(3,5));assertEquals(1,cm.getNumOfCoupsCanUse(3,1));//边界检查assertEquals(0,cm.getNumOfCoupsCanUse(0,5));assertEquals(3,cm.getNumOfCoupsCanUse(4,5));}}运行结果为:3、完成程序publicintgetNumOfCoupsCanUse(intmonths,inttotalCoups){if(months==1){returntotalCoups=1?1:0;}elseif(months==2){returntotalCoups=2?2:totalCoups;}elseif(months=3){returntotalCoups=3?3:totalCoups;}else{return0;}}运行测试:4、优化程序publicintgetNumOfCoupsCanUse(intmonths,inttotalCoups){if(months1||months3){return0;}return(totalCoups=months)?months:totalCoups;}运行测试:业务变更:增加6个月选择1、用户可以选择付费月份为1、2、3、6个月2、用户选择1个月最多可用1个红包3、用户选择2个月最多可用2个红包4、用户选择3个月最多可用3个红包5、用户选择6个月最多可用3个红包更改测试publicvoidtestGetNumOfCoupsCanUse(){CouponManagerImplcm=newCouponManagerImpl();assertEquals(0,cm.getNumOfCoupsCanUse(1,0));assertEquals(1,cm.getNumOfCoupsCanUse(1,1));assertEquals(1,cm.getNumOfCoupsCanUse(1,5));assertEquals(2,cm.getNumOfCoupsCanUse(2,5));assertEquals(3,cm.getNumOfCoupsCanUse(3,5));assertEquals(1,cm.getNumOfCoupsCanUse(3,1));assertEquals(1,cm.getNumOfCoupsCanUse(6,1));assertEquals(3,cm.getNumOfCoupsCanUse(6,5));//边界检查assertEquals(0,cm.getNumOfCoupsCanUse(0,5));assertEquals(0,cm.getNumOfCoupsCanUse(4,5));assertEquals(0,cm.getNumOfCoupsCanUse(7,5));}运行结果:重构程序/***根据选择充值月数和拥有的最大红包数,取得可用红包数**@parammonths充值月数*@paramtotalCoups拥有的最大红包数*@return可用红包数*/publicintgetNumOfCoupsCanUse(intmonths,inttotalCoups){if(months=1&&months=3){return(totalCoups=months)?months:totalCoups;}elseif(months==6){return(totalCoups=3)?3:totalCoups;}else{return0;}}运行测试:Agent1•敏捷开发概述2•测试和开发之间的关系3•测试驱动开发4•结对5•总结6•Q&A小时候结对学习小时候结对学习的关键词长大了要结对编程结对编程的关键词结对中需要做的需求review设计reviewCodereview进度review结对的好处互相学习,学习人家的设计思路、开发技巧互相backup提高产品质量促进沟通促进问题及时反馈结对中的取舍不是结对编程,而是结对开发无需两两同时进行需要根据项目的大小和难易而定Agent1•敏捷开发概述2•测试和开发之间的关系3•测试驱动开发4•结对5•总结6•Q&A总结有哪个项目不感叹测试资源投入太少呢?我们现在的开发和测试比例还是3:1,那google如何做到10:1?5个人做一个月的项目,bug数超过100,算是质量高吗?项目需求日益变化,代码重构的必要性很高,如何让重构有个保障呢?复杂的流程难以测试,应该怎样去完善可测试性呢?总结孰能无过?每个人都会犯错误。不能把错误留给测试。编码规范、设计原则无法很好地执行。团队成员变化较大,复杂逻辑的模块其他开发成员很难接替。产品质量所有人都具有重要的责任团队成员如何在项目中互相学习?Q&A
本文标题:敏捷开发之测试驱动开发和结对
链接地址:https://www.777doc.com/doc-5089938 .html