您好,欢迎访问三七文档
单元测试?TestBriefAgenda程序员为什么要做测试测试的一些基本概念测试先行的概念单元测试的基本做法和常见工具测试不是我的工作你是这样的程序员么?测试是测试部门的责任,我的责任应该关注在写代码上测试不是一种技术工作,毫无乐趣可言,请不要骚扰我。我可是一个了不起的EJB程序员我们有测试人员,有集成/系统/确认测试,他们迟早会发现我的错误。请不要浪费我的时间。不要侮辱我,我写的程序,怎么可能有错误。测试是完全没必要的。离我远一点,我是程序员你做了测试了吗?大部分中小公司,和软件开发管理处于早期阶段的团队,没有专门的测试工作和测试流程,测试只是在产品提交给用户之前,组织若干人员对最终产品作一次基本功能的确认测试而已。更多时候,测试的实际工作是用户来完成的。后果软件的质量完全取决于程序员的个人技能和责任心,具有很大的随机性后期维护成本高昂1个月的开发,几天的测试,然后花1,2年的时间去修补错误这个项目我已经维护了3年了根本原因是软件自身复杂的结构虫虫和天上的星星一样多软件的结构方法类功能模块系统用户需求系统结构集成单元错误可能会随机的分布在任何一个地方测试模型软件自身的复杂程度决定了即使是最优秀的程序员也不可能不制造任何错误。软件自身的复杂程度决定了不可能只通过对最终产品的1,2种类型的测试就可以排除系统中的大部分错误测试必须并行的融入到软件开发生命周期的各个阶段,以覆盖软件结构和开发生命周期的不同关注点。主要的模型有传统的瀑布模型,和v模型,以及改良的x模型V模型测试活动融入整个软件开发的生命周期不同阶段的测试强调的是从不同视角关注不同的方面,尽可能早而全的出去错误,不累计错误。每一种类型测试的效果,将严格依赖于前期阶段其他类型测试的执行的正确,完整与否。测试有分工,合适的人在合适的时候承担合适的测试改良的有x模型时间和成本缺陷的发现时间越晚,修复的成本越高,在部署阶段每个缺陷的修复成本都会及其高昂(每一个major以上的缺陷修复都不得不作完整的系统测试和确认测试),严格实施scm的组织尤其昂贵。什么是单元测试单元测试测试的软件最小的可执行单元的正确性,即类或方法单元测试通常是一段可执行代码,并能验证执行结构是否和预期相等每个单元测试至少应该有两个测试例子(TestCase):Negative/Positive单元测试可以是黑盒也可以是白盒,取决于执行方法盖房子,至少要保证每一块砖都是好的什么是单元测试(UnitTest)单元测试是其他类型测试的基础。不认真,完整的单元测试会导致其他类型测试起不到好的效果程序员最了解自己的程序单元,最适合做单元测试传统的重量级的方法学里,UTtestcase由设计人员在系统设计阶段开发,并用来验证编码人员的工作质量盖房子,至少要保证每一块砖都是好的单元测试是成本最低的测试活动发现一个Defect所需要的时间91年数据程序员的责任程序员的价值在于和他人合作,开发出高质量的代码,而不是一堆新技术名词堆砌的虫件(bugware)。程序员必须对自己的代码质量负责,单元测试是对自己代码质量的基本承诺。程序=UT+CODE不做单元测试,就会影响团队其他人员的工作。测试人员有权利对没有做过UT的代码说No.不愿意做UT的人,不属于任何团队。程序=UT+CODE实践证明(个人工作经历)代码质量最好的程序员是UT做的最好的程序员。开发速度最快的程序员,是UT做的最好的程序员80%以上的非需求性错误,都集中在没有做UT和不方便做UT的代码块。UT的质量直接影响了IT/ST/UAT的质量。程序=UT+CODE测试很重要,但是我已经调试运行过代码了,他应该是正确的,为什么还要浪费额外的时间程序已经能跑起来了,这期间我实际已经手工作了测试,只是没有记录和编写代码而已我没有时间做测试,工期已经很紧张了,能写完代码就不错了,虽然我知道以后要返工。我不知道应该怎么样去做测试调试不等于UT调试只会关注于程序的某个方面,通常是最优路径。UT至少要关注正/负2个方面,还需要保证一定的覆盖率调试,尤其是J2EE应用的调试要耗费大量的时间,没有UT的效率高(后面再细讲)调试不可重现,在代码变跟以后,软件质量无法保证UT一定要做到自动化只有用代码编写的UT,才能够重现,才能真正节约未来手工测试的时间。只有用代码编写的UT,才能做到自动化,才能在软件开发的任何时候都能快速,简单的大批量执行,保证能准确地定位错误,保证不会因为修改而引入新的错误。在系统开发的后期尤为明显。自动化的UT,才能保证回归测试的有效执行。UT节约的是你未来的时间编写UT代码的时间节约了未来修改/维护低质量代码的时间学习做UT的时间,是为了以后你可以更好的关注你的代码如果使用Test-driven的思想自身就变成设计的一部分,你不会再感到是在浪费时间,编写UT的过程,就是设计的过程UT快速的定位错误所在,节约了你调试的时间。需求设计评审编码reworkUT如何进行UT---传统的做法,在it之前进行UT严格的瀑布模型,UT作为生命周期的一个阶段UT的TestCase一般做为设计的一部分。UT的执行通常在代码review以后Testcase单独编写和执行成本高昂,尤其是严格执行SCM的情况。UT本身是作为一种最终的质量检测手段,只能节约未来的时间.完整全面的UT需要大量的时间,精力,需要和PR结合程序员通常感觉不到UT带来的眼前好处,得不到任何乐趣,抵制执行。如何进行UT---传统的做法*场景程序员先开始设计数据表。然后开始依次编写数据访问对象,strustaction,jsp页面。他检查了一遍代码,确定每件事看起来都是不错的,于是他开始把所有的东西集成在一块。当然,通常是跑不起来的,经过若干个小时辛苦的调试,中间不断的修改代码,重起appserver。终于在数据访问对象中发现了一个错误。若干时间以后,在代码被review以后,程序员开始做枯燥无味的单元测试工作,这个时候,他最想做的事情其实是睡觉。迫于时间和成本的压力,pm/程序员往往会简化或者不执行UT的过程需求设计运行ut,定位错误编码rework编写Testcase如何进行UT---改良,写一点,测一点程序员每编写完一个程序单元,就编写UT代码首先通过运行UT代码来定位程序的错误,而不是直接调试代码,节约了大量调试的时间。如果能把程序划分为尽可能小的单元,通过执行ut代码,就能快速的定位错误的所在,调试就可以避免可有效的保证以前编写的代码的正确性,不需要拖到增量结束以后再执行。错误能尽早的发现,不需要等到Codereview以后再修复,成本很低Codereview如何进行UT---改良,写一点,测一点程序员开始设计数据库表,然后开始编写数据访问对象,接着他对数据访问对象编写了UTtestcase,运行TC,发现了若干错误,然后迅速的改正了他。所有的TC都通过以后,他开始编写ACTION,同样,他对ACTION做了些测试。最后他编写了JSP,并把所有的东西集成在一起,当然因为JSP的不好测试性,他花了点时间在修订JSP页面的几个TAG错误上。若干时间以后,在做IT之前,他去问QA部门的人,你看,我所有的代码都写了UTTC,这些TC能不能直接作UT的REPORT呢?在得到确定的回到以后,他很高兴得回去做别的事了。UT作为一种帮助提高开发效率的有效手段融入到开发过程中,程序员也不需要再去做枯燥无聊的事后UT了如何进行UT---改良,写一点,测一点.实践在一段时间以后,我发现如果自己不写UT,我的开发速度就开始大打折扣我的一位同事在1个月以后,很乐于向我展示作UT的好处。每次他做任何修改,他都可以通过执行所有UT的SUITE来确保没有引入任何新的错误,节约了大量的时间,看到屏幕上的一排绿灯,那种心情非常好。“整个团队只有我能按时下班,终于CTO问我为什么,我告诉他,我总是在做UT,所以我很少化时间去做调试。”编程的80%时间都是用在调试,节约了调试的时间,也就提高了开发的速度每次看到绿灯的时候,心情就很好如何进行UT---改良,写一点,测一点缺点经常性的,当你写完一个方法,你或许过于自信,而不愿意再去为他写一个testcase.若干时间以后,你发现他的问题终于出来了有时候,当辛苦编写完代码,开始编写testcase的时候,你会发现因为设计上错误,这段代码是不可以测试的。这就为未来留下了隐患如何进行UT–测试驱动的做法失败通过时间单元测试100%通过设计先写单元测试重构运行单元测试编程发现BUG如何进行UT–测试驱动的做法先写Testcase,可以保证我们每一个public/protected的方法都确实有TestCase编写testcase的过程也就是一个设计的过程你需要考虑实现代码的可测试行你需要考虑代码和测试代码的关系,仔细考虑实现代码的边界和逻辑,测试代码应该如何保证实现代码的正确性当测试代码完成的时候,就会对实现代码有清晰地了解你仔细思考要做什么和不要做什么,可以避免过度设计此时的UT实际是白盒测试,能起到更好的效果。可以把关注点放在某些重要的地方。Example通过测试代码来思考设计//空置必须抛出异常Try{boy.add(null);fail(“don’tthrowexception”);}catch(xxx){}//add//boy.add(newBoy());Stringid=boy.add(newBoy());//需要检测是否增加成功,那么add就应该返回id值,修改上面的代码assertEqual(id,boy.find(id).getID())If(value=null){thrownewIllegalArguementException(‘xxx’);}Stringid=DAOSupport.addObject(boy);Returnid;Testcaseadd如何进行UT–测试驱动的做法Test-DrivenDesign是一种开发风格,它要求程序员做到:在写产品代码之前,先写它的单元测试(UnitTests)没有单元测试的Class不允许作为产品代码单元测试例子决定了如何写产品代码不断地成功运行所有的单元测试例子不断的完善单元测试例子Test-DrivenDesign是把需求分析,设计,质量控制量化的过程!也是一个对软件持续改进的过程如何进行UT–测试驱动的做法测试代码/实现代码的交替编写,能让大脑始终处在一种松驰/紧张,工作效率会比较高。编写测试代码也是设计的过程,总体的时间花费就下降了,也避免了因为对不可测试代码的修改而导致的时间成本文物之道,一张一弛常用单元测试框架JUnitStrutstestcase,junit的扩展,用于测试struts的actionHttpUnit测试http页面JFCUnit.Cactus专门用来测试服务器类JsUnit测试javascriptJUnit一个开源的单元测试框架,也是其他java单元测试框架的基础JUnitTestcasepublicclassTestPersonextendsTestCase{/**Aunittesttoverifythenameisformattedcorrectly.*/publicvoidtestGetFullName(){Personp=newPerson(Aidan,Burke);assertEquals(AidanBurke,p.getFullName());}/**Aunittesttoverifythatnullsarehandledproperly.*/publicvoidtestNullsInName(){Personp=newPerson(null,Burke);assertEquals(?Burke,p.getFullName());//thiscodeisonlyexecutediftheprevio
本文标题:软件单元测试技巧
链接地址:https://www.777doc.com/doc-3564510 .html