版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
测试驱驱动的的设计计和开开发(TestDrivenDesignandDevelopment)基础篇篇111111你的代代码工工作吗吗?“这段段代码码很简简单,,不可可能出出错””“我试过过了,,它是是正常常工作作的呀呀”“我用用Debugger测试过过了,,我遍遍历了了所有有程序序分支支,内内存中中的值值都是是对的的”最好的的方法法是写写一段段另外外的代代码来来证明明它,让电电脑来来告诉诉我们它它是工工作的的。111112XP中的测测试UnitTestAcceptanceTest(FunctionalTest)RegressionTestNightlyTestStressTest所有的的测试试都应应该独独立地地自动动的运运行111113什么是是单元元测试试(UnitTest)单元测测试是是一段段能够够放在在批处处理中中自动动运行行的,,用来来测试试Classes的的程序。。单元元测试试测试试一小小段代代码或或一个个足够够小的的功能能。单单元测测试程序序调用用这小小段代代码或或功能能,并并验证证返回回的结结果是是否符符合预预先设设定的结结果。。每个单单元测测试至至少应应该有有两个个测试试例子子(TestCase):NegativePositive单元测测试是是软件件工程程的一一个关关键部部分。。111114什么是是AcceptanceTestAcceptanceTestareprogramsorscriptsconfiguredtotestthatpackages(groupsofclustersofclasses)meetexternalrequirementsandachievegoals,suchasperformance.Theyincludescreen-drivingprogramsthattestGUIsfromwithout.AcceptanceTest是对软软件做做End-To-End的测试试,衡衡量软软件是是否符符合用户需需求的的指标标,也也就是是验收收测试试。111115什么是是RegressionTest“Regressiontestingistheprocessofvalidatingmodifiedpartsofthesoftwareandensuringthatnonewerrorsareintroducedintopreviouslytestedcode.”一句话话,RegresstionTest就就是要要重新新测试试所有有的代代码和和功能能。RegressionTest和DevelopmentTest的不同同在于于RegressionTest需要重重用已已经建建立的的所有有的测测试单单元(UnitTest)和功能能测试试套件件(FunctionalTest)。RegressionTest的基础础是完完整的的自动动单元元测试试和功功能测测试。。111116什么是是NightlyTestNightlyTest就是每每晚自自动运运行所所有的的UnitTest和AcceptanceTest。NightlyTest是是XP中的的ContinuousTest的的一个个练习习(Practice)。NightlyTest可可以准准确的的反映映项目目开发发的进进度和和质量量。111117NightlyTestNightlyTest是软件件开发发中一一个保保证开开发之之质量量的最最有效效的方方法,,也是衡量量软件件之质质量和和开发发效率率的最最好的的指标标。NightlyTest就是每每天工工作结结束,,所有有的代代码都都Checkin到SourceControl后,自自动运运行所所有的的UnitTest和FunctionTest。测试试的结结果应该自自动分分发给给开发发人员员和管管理层层。两个指指标数数值::测试例例子的的通过过率––单元测试试必须须是100%通过。。FunctionalTest应该按按计划划的通通过。。单元测试的的覆盖率––表明有多少少Class被测试过和和测试的完完善程度。。111118测试优先的的编程在写任何代代码之前,,先写它的的UnitTest。“Neverwritealineoffunctionalcodewithoutabrokentestcase”KentBeckTest-FirstProgramming是一种测试试技术吗??Test-FirstProgramming首先是一种种分析方法法。它迫使使程序员仔仔细思考要要做什么和和不要做什什么(而不是如何何具体的实实现)。特特别是各种种例外的情情况,并用用程序语言言正式的写写下来。这这就好像在在程序员的的任务和程程序员之间间签订了一一个清晰的的正式合同同。Test-FirstProgramming是一一种设计方方法。UnitTest测测试的事程程序,而不不是一个想想法。程序序员必须清清晰的定义义程序的界界面才能写写出它的UnitTest。而这时时程序员是是不知道((也不需要要知道)里里面的具体体逻辑是如如何实现的的。程序员员只需要考考虑Class的界界面和功能能(Responsibility)。啊,你你在做OO设计了。。Test-FirstProgramming是一种质量量控制方法法(QualityControl)。。如何控制制质量呢??如何知道道我的程序序是否运行行呢?我会会不会漏了了什么?运运行一下UnitTest。Test-FirstProgramming是一种重构构和优化的的方法。我我们总希望望自己的代代码可以漂漂亮,运行行的效率高高,所以我我们会不断断地去改进进。可是如如何保证改改进和优化化后的质量量呢?会不不会越改越越糟?答案案还是UnitTest。。Test-FirstProgramming不是通常意意义上的测测试技术,,它的目的的也不是仅仅仅用来测测试你的代代码。Test-FirstProgramming是一种面向向对象的开开发方法。。111119什么是Test-DrivenDesign(TDD)Test-DrivenDesign是一种开发发风格,它它要求程序序员做到::在写产品代代码之前,,先写它的的单元测试试(UnitTests)没有单元测测试的Class不不允许作为为产品代码码单元测试例例子决定了了如何写产产品代码不断地成功功运行所有有的单元测测试例子不断的完善善单元测试试例子Test-DrivenDesign是把需需求分析,,设计,质质量控制量量化的过程!1111110为什么会出出现TDD现实中的设计(Design)和测试(Testing):面对一个新新的开发任任务,往往往第一个念念头就是如如何去实现现它呢?“好像是这这样做的””感觉上上差不多了了。抓起任务就就开始编码码,一边写写,一边修修改和设计计。哎,时间很很紧。我先先把任务实实现了,然然后再好好好测试。还是不工作作,时间不不多了。做做个快速但但丑陋的修修改吧。等等有空来再再来重新整整理这些代代码吧。用Debugger运行几次次代码,走走完所有的的我认为可可能的分支支。我感觉觉这些代码码应该行了了。提交吧吧。哎,我也知知道该写一一些自动的的单元测试试来把刚才才在Debugger中的测测试走一遍遍。可是那那是很多的的活啊。这种情况要要作自动测测试太复杂杂了。还是是手工作一一下测试好好了。1111111为什么会出出现TDD(Continue)程序员心中中的测试::很郁闷的工工作。对啊啊,程序员员该做些新新的,有创创意的东西西嘛。写一一些新的功功能会更有有趣些。我知道这些些代码会工工作的。我我的经验和和感觉都这这样告诉我我。只要没没人乱改我我的代码,,应该就没没问题。再再说这些边边缘情况几几乎不可能能出现了。。测试是QA的工作。自动测试太太花时间((我要赶Deadline),不值得得。1111112如何面对这这些现实和和想法Test-DrivenDesignandDevelopment真的能行??试一试!1111113如何做TestDrivenDesignandDevelopment再开发一个个新的功能能之前首先确定你你要做什么么(不是要要如何做!!)比如说一个个论坛的增增加用户的的功能,我我们需要又又一个method来增加一个个用户:publicvoidaddAccount(Accountaccount)当然包括成成功增加一一个用户((在数据库库中插入一一条纪录))还包括如果果已经由一一个相同的的用户,应应该返回一一个用户已已存在的消消息OK,我们知道这这个method中的这段代代码要做什什么,而且且这段代码码也足够简简单。1111114如何做TestDrivenDesignandDevelopment
(Continue)然后为这个个功能(Method)写单元测试试例子(UnitTest)单元测试例例子要覆盖盖这个Method的“做什什么”。所以我们至至少有了两两个测试例例子:TestCase1:测试成功增增加一个用用户TestCase2:测试增加一一个已存在在的用户其他边缘情情况测试::TestCase3:传入的Account对象为NULL1111115如何做TestDrivenDesignandDevelopment
(Continue)写Production代码我们清楚知知道这段代代码需要做做什么。因因为我们有有另一段代代码摆在那那里,清晰晰的表明这这段代码的的Contracts。不用多,也也不能少,,只需要能能实现再UnitTest中的Contracts和能能够够通通过过它它的的UnitTest。。1111116如何何做TestDrivenDesignandDevelopment((Continue)运行行UnitTest如果果顺顺利利通通过过,,你你已已经经很很好好的的完完成成了了你你的的任任务务。。如果果没没通通过过,,修修补补代代码码直直到到能能通通过过UnitTest为止止。。如果果出出现现在在UnitTest中没没预预先先设设定定的的结结果果,,在在UnitTest中增增加加一一个个TestCase,,修补补代代码码直直到到通通过过所所有有的的TestCase为止止。。1111117TDD和PSPPersonalSoftwareProcess的DevelopmentDesignCodeBuildTestTest-DrivenDesignandDevelopmentAnalysisCodeUnitTestCodeBuildRunTestAnalysisDesign1111118XP采用用了了TDDTDD是ExtremeProgramming中必必须须遵遵行行的的一一个个方方法法。。TDD是XP中PairProgramming的工工作作模模式式。。XP中中把把测测试试驱驱动动的的设设计计和和开开发发做做到到极极致致。。TDD的整整个个流流程程由由两两个个程程序序员员一一起起执执行行。。XP正正是是因因为为采采用用了了TDD才能能够够做做到到每每天天的的代代码码都都是是ProductionCode和每每个个小小的的Release都能能提提供供具具备备Production质量量的的代代码码并并投投入入使使用用。。有了了TDD,XP才能能降降低低风风险险,,去去拥拥抱抱变变化化。。有了了TDD,XP才能能在在计计划划的的时时间间内内完完成成计计划划质质量量的的代代码码。。有了了TDD,XP才能能减减少少Code<->Fix环节节,,从从而而减减少少项项目目成成本本。。有了了TDD,XPTeam才能能对对自自己己的的工工作作充充满满自自信信。。1111119TDD防止止Over-Engineering在开发中采用用TDD,可以有效的的避免过度设设计和开发。。如果程序员员不愿为一个Method写测试例子或或者认为现在在没有必要测测试改Method,那这个Method多半半是现在不需需要的。1111120TDD,程序员和管管理层对程序员来说说,通过运行行UnitTest和FunctionalTest,,每天下班的时时候都可以清楚楚的知道自己己的代码是work的。对管理层来说说,通过NightlyTest的结果,每天天一早都清楚楚的知道项目的质量和开开发进度。1111121XP中谁来写TestsDeveloper:UnitTestAcceptanceTest(FunctionalTest)Customer:AcceptanceTestCustomer为每一个UserStory写FunctionalTest。但通常用户户并不具备设计和开开发FunctionalTest的能力,需要要程序员的帮帮助。1111122什么时候写Tests?如果你要写一一个新的功能能,请先写她她的测试例子子如果你要在没没有经过测试试的代码上写写新的功能,,请先写目前前代码的测试试例子如果你要Fix一个Bug,请先为这个个Bug写一个测试例例子如果你要Refactor没有测试试过的代码,,请先写一个个测试例子如果你发现一一个边缘例外外值,请为她她写一个测试试例子1111123ExtremeUnitJunitJavaClass的测试FrameworkJFCUnit JavaSwingapp的测试FrameworkCatusJavaServerSide(EJB,Servlet)的测试FrameworkHTMLUnit HtmlPage的测试FrameworkHTTPUnit HtmlPage的测试FrameworkCPPUnit C++测试Framework.NetUnit .Netapp的测试Framework……1111124Junit(Asample)Junit是由kentBeck和ErichGamma编写的一个opensource的测试框架,用来编编写可重复的的测试例子。。测试论坛中的的增加用户methodpublicclassAccountDAOmySqlimplementsAccountDAO{/***Addauseraccount**@paramAccount-Aaccountobjectthatcontainstheuserinfo,likeuserName,*password,email*/publicvoidaddAccount(finalAccountaccount)throwsSQLException,AccountAlreadyExistException{……}1111125Junit(Asample)1.为对应的JavaClass建立一个TestCase。UnitTestCase应该放放在和BusinessClass相相同的Package中中,但在不同同的的物理位位置。packageorg.redsoft.forum.dao.mysqlimportjunit.framework.TestCase;importjunit.framework.TestSuite;importjunit.framework.Test;publicclassAccountDAOmySqlTestextendsTestCase{publicAccountDAOmySqlTest(Stringname){super(name);}}1111126Junit(Asample)2.OverridesetUp()andtearDown()如果需要,可可以在setUp()中初始化需要要的全局变量量,资源等((比如DatabaseConnection,FileI/O或MockObjects等)相应的,可以以在tearDown()中释放资源((DatabaseConnection,FileI/O和MockObjects等)publicclassAccountDAOmySqlTestextendsTestCase{……privateMysqlFixturemysqlFixtureIns=newMysqlFixture();publicvoidsetUp()throwsException{mysqlFixtureIns.setUp();}publicvoidtearDown()throwsException{mysqlFixtureIns.tearDown();}}1111127Junit(Asample)3.为被测试试的Method写TestCase……publicvoidtestAddAccountNormal(){AccountDAOmySqldao=newAccountDAOmySql();Accountaccount=newAccount(USER_NAME,"charles","charles_hhb@");try{dao.addAccount(account);Accountaccount_new=dao.findByUserName(account.getUserName());assertEquals("Expectingcharles",account.getUserName(),account_new.getUserName());assertEquals("Expectingcharles",account.getPassword(),account_new.getPassword());assertEquals("Expectingcharles@",account.getEmail(),account_new.getEmail());dao.removeAccount(account.getUserName());}catch(finalExceptione){e.printStackTrace();fail("Unexpectedexception::"+e.toString());}}1111128Junit(Asample)publicvoidtestAddAccountAlreadyExist(){AccountDAOmySqldao=null;Accountaccount=null;try{//AddanAccount……dao.addAccount(account);fail("AccountAlreadyExistExceptionexpected");}catch(finalSQLExceptione){e.printStackTrace();fail("Unexpectedexception::"+e.toString());}catch(finalAccountNotFoundExceptionnotFound){notFound.printStackTrace();fail("Unexpectedexception:"+notFound.toString());}catch(finalAccountAlreadyExistExceptionex){//Passtry{dao.removeAccount(account.getUserName());}catch(finalSQLExceptionsql){sql.printStackTrace();fail("Unexpectedexception");}}}1111129Junit(ASample)运行这个UnitTest。Junit提提供两种运行行界面:Swing(junit.swingui.TestRunner)C:\sandbox\forum>java-classpath./classes;./lib/junit.jar;./lib/mysql_jdbc.jar;./lib/Tidy.jar;./lib/struts.jarjunit.swingui.TestRunnerorg.redsoft.forum.dao.mysql.AccountDAOmySqlTest1111130Junit(ASample)Text界面面(junit.textui.TestRunner)1111131JunitTestSuiteTestSuite用来运行所有有的UnitTestsTestSuite的的数型结构::org.redsoft.forum.AllTest||org.redsoft.forum.dao.AllTest| || |org.redsoft.forum.dao.mysql.AllTest||org.redsoft.forum.util.AllTest每个PackageLevel都都由一个AllTestTestSuite在每个TestSuite中,加入在本packagelevel中的所有有单元测试例例子(UnitTestCases)加入子Packagelevel中的所有AllTestSuite1111132JunitTestSuitepackageorg.redsoft.forum.dao;publicclassAllTests{publicstaticvoidmain(Stringargs[]){junit.textui.TestRunner.run(suite());}publicstaticTestsuite(){TestSuitesuite=newTestSuite();//加入子子package中的AllTestsuitesuite.addTest(org.redsoft.forum.dao.mysql.AllTests.suite());//加入本本packagelevel中的的UnitTestcasesuite.addTestSuite(MysqlDataSourceTest.class);returnsuite;}}//EOC1111133JFCUnit一个Junit的Extension,用来测试Swing-based的Application。一个最简单的的Sample:测试一一个LoginScreen1111134JFCUnit代码片断:设设置测试环境境privateLoginScreenloginScreen=null;privateTestHelperhelper=null;publicLoginScreenTest(Stringname){super(name);}protectedvoidsetUp()throwsException{super.setUp();helper=newJFCTestHelper();loginScreen=newLoginScreen("LoginScreenTest:"+getName());loginScreen.setVisible(true);}protectedvoidtearDown()throwsException{loginScreen=null;helper.cleanUp(this);super.tearDown();}代码片断:测测试图形界面面JDialogdialog;JButtonexitButton=(JButton)helper.findNamedComponent("ExitButton",loginScreen,0);assertNotNull("CouldnotfindtheExitbutton",exitButton);JButtonenterButton=(JButton)helper.findNamedComponent("EnterButton",loginScreen,0);assertNotNull("CouldnotfindtheEnterbutton",enterButton);JTextFielduserNameField=(JTextField)helper.findNamedComponent("LoginNameTextField",loginScreen,0);assert
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 核磁科护理工作总结
- 教育培训行业工程师工作总结
- 电商供应链管理总结
- 初中班主任工作感悟与反思
- 婚纱店前台工作心得
- 教育科研行业教学改革建议
- 2024年度企事业单位聘用司机及车辆安全培训服务合同3篇
- 得寿山石默想语文阅读理解
- 白鹅微课程设计
- 波形发生器的课程设计
- 施工项目农民工工资支付无欠薪承诺书
- 设计中的重点、难点及关键技术问题的把握控制及相应措施
- 幼儿园教学活动 幼儿园教学活动概述 幼儿园教学活动的特点
- 6.2.1向量的加法运算 课件(共14张PPT)
- YY/T 1866-2023一次性使用无菌肛肠套扎器胶圈或弹力线式
- 海蒂(世界文学名著经典)
- 中国马克思主义与当代知到章节答案智慧树2023年西安交通大学
- 变电站检修规程完整
- 海南文昌2x460MW级燃气-蒸汽联合循环电厂
- 形式逻辑学全套课件
- 姜安《政治学概论》(第2版)笔记和典型题(含考研真题)详解
评论
0/150
提交评论