您好,欢迎访问三七文档
当前位置:首页 > 中学教育 > 初中教育 > Junit单元测试技术
Junit单元测试技术讲解人:邱百超Email:badqiu(a)gmail.com讲解内容测试技术介绍JUnit3.8单元测试及实例单元测试最佳实践MockObjects技术JUnit相关工具及其扩展Spring对测试的支持JUnit4.0介绍测试驱动开发(TDD)Q&A软件测试类型1软件测试类型2单元测试:测试单个对象是否工作正确集成测试:测试多个对象之间,多个子系统之间以及系统环境配置是否工作正确功能测试:测试整个应用是否工作正确性能测试:测试系统的性能验收测试:验证用户是否喜欢我的程序单元测试由谁编写程序员本身程序员PairsJUnit开源的Java单元测试框架结构:TestSuitesTestCase[Javaclass]Test[Javamethod]Fixtures:commonsetup/teardowncodeJUnit3.8例子importjunit.framework.TestCase;publicclassStringTestextendsTestCase{publicvoidtestReplace(){Stringresult=abc.replace('a','b');assertEquals(bbc,result);}publicvoidtestSubstring(){Stringresult=abc.substring(1);assertEquals(bc,result);}}断言(assert)assertFalseassertEqualsassertNotEqualsassertNullassertSame…运行JUnit測試(TestRunner)命令行JUnit自帶的Swing界面IDE集成(Eclipse,Netbean)Ant,Maven最佳实践1(Test命名及存放)1.相同的package不同的存放位置2.Calucator的测试类为CalucatorTest3.add()的测试方法为testAdd()最佳实践2细粒度的测试一个测试只测试一个方法(或多个测试测试一个方法)测试隔离测试之间相互独立,没有依赖性為assert增加描述TestCase生命周期(例子)TestSuites(一组测试)publicclassAllTests{publicstaticvoidmain(String[]args){junit.textui.TestRunner.run(AllTests.suite());}publicstaticTestsuite(){TestSuitesuite=newTestSuite(Testforjunitdemo);//$JUnit-BEGIN$suite.addTestSuite(StringTest.class);suite.addTestSuite(CalucatorTest.class);//$JUnit-END$returnsuite;}}评估测试结果测试结果报告代码测试覆盖率报告测试报告(例子)测试覆盖率报告(例子)最佳实践自动化运行测试持续集成(CruiseControl)测试技巧异常(exception)测试MockObjects技巧:Exception测试MockObjects测试技术允许你测试依赖于其它对象的方法,但那个对象非常难实例化或是太慢等.例1要测试Servlet的doGet()请求:HttpRequest,HttpResponse可以使用Mock例2要测试Service层的逻辑,但dao层要依赖数据库或是dao层只提供一个接口没有实现类Mock转帐实例1Mock转帐实例2(Account对象)publicclassAccount{privateStringaccountId;privatelongbalance;publicAccount(StringaccountId,longinitialBalance){this.accountId=accountId;this.balance=initialBalance;}publicvoiddebit(longamount){this.balance-=amount;}publicvoidcredit(longamount){this.balance+=amount;}publiclonggetBalance(){returnthis.balance;}}Mock转帐实例3publicinterfaceAccountManager{AccountfindAccountForUser(StringuserId);voidupdateAccount(Accountaccount);}publicclassAccountService{privateAccountManageraccountManager;publicvoidsetAccountManager(AccountManagermanager){accountManager=manager;}publicvoidtransfer(StringsenderId,StringbeneficiaryId,longamount){Accountsender=accountManager.findAccountForUser(senderId);Accountbeneficiary=accountManager.findAccountForUser(beneficiaryId);sender.debit(amount);beneficiary.credit(amount);this.accountManager.updateAccount(sender);this.accountManager.updateAccount(beneficiary);}}Mock转帐实例4(MockObject)publicclassMockAccountManagerimplementsAccountManager{privateHashtableaccounts=newHashtable();publicvoidaddAccount(StringuserId,Accountaccount){this.accounts.put(userId,account);}publicAccountfindAccountForUser(StringuserId){return(Account)this.accounts.get(userId);}publicvoidupdateAccount(Accountaccount){//donothing}}Mock转帐实例5(测试)publicclassTestAccountServiceextendsTestCase{publicvoidtestTransferOk(){//使用MockAccountManagerMockAccountManagermockAccountManager=newMockAccountManager();AccountsenderAccount=newAccount(1,200);AccountbeneficiaryAccount=newAccount(2,100);mockAccountManager.addAccount(1,senderAccount);mockAccountManager.addAccount(2,beneficiaryAccount);AccountServiceaccountService=newAccountService();accountService.setAccountManager(mockAccountManager);//转帐操作accountService.transfer(1,2,50);//验证assertEquals(150,senderAccount.getBalance());assertEquals(150,beneficiaryAccount.getBalance());}}JMock快速创建mockobjects使用动态生成代理避免需要手工编写MockObject实现JMock2.4.0转帐实现publicclassJMockAccountServiceTestextendsTestCase{Mockerycontext=newMockery();publicvoidtestTransferOk(){finalAccountsenderAccount=newAccount(1,200);finalAccountbeneficiaryAccount=newAccount(2,100);//使用MockAccountManagerfinalAccountManagermockAccountManager=context.mock(AccountManager.class);context.checking((newExpectations(){{one(mockAccountManager).findAccountForUser(1);will(returnValue(senderAccount));one(mockAccountManager).findAccountForUser(2);will(returnValue(beneficiaryAccount));one(mockAccountManager).updateAccount(senderAccount);one(mockAccountManager).updateAccount(beneficiaryAccount);}}));AccountServiceaccountService=newAccountService();accountService.setAccountManager(mockAccountManager);//转帐操作accountService.transfer(1,2,50);//验证assertEquals(150,senderAccount.getBalance());assertEquals(150,beneficiaryAccount.getBalance());}}为何没有测试Account对象最佳实践只测试有可能导致失败的原因(如简单的值对象不用测试)將private的方法改為package以便測試为测试修改代码以便测试测试驱动开发(TDD)极限编程的重要特点基本思想就是在开发功能代码之前,先编写测试代码。为什么编写单元测试更好的测试覆盖率(如某个if条件)提升对你编写的代码信心为重构提供支持代码即是文档提升设计团队协作可以快速的测试你的代码(避免启动服务器等)单元测试类型逻辑单元测试(JUnit)集成单元测试功能单元测试(Selenium)单元测试的使用普通的单元测试使用流程修正一个bug或重构代码运行测试确保修改正常提交修改至svnorcvs单元测试的基本原则为了能够自动化运行测试容易编写容易运行容易识别(可以容易查看那里pass,那里failure)可以重现Spring对测试的支持WebmockJndimock数据库测试支持Spring对数据库测试的支持AbstractTransactionalDataSourceSpringContextTestsSpring对Mock的支持MockHttpServletRequestMockHttpServletResponseSomeServlet.service(MockHttpServletRequest,MockHttpServletResponse)JndiMockSelenimu功能测试工具可以模拟用户的操作验证结果JUnit4.0介绍兼容3.8.1不用强制继承TestCase类使用注解(Anno
本文标题:Junit单元测试技术
链接地址:https://www.777doc.com/doc-3185543 .html