play手把手教你创建一个博客项目10完整的应用程序测试.docx
《play手把手教你创建一个博客项目10完整的应用程序测试.docx》由会员分享,可在线阅读,更多相关《play手把手教你创建一个博客项目10完整的应用程序测试.docx(10页珍藏版)》请在冰点文库上搜索。
play手把手教你创建一个博客项目10完整的应用程序测试
play手把手教你创建一个博客项目10完整的应用程序测试
现在,我们差不多终止了博客引擎的编码工作,但对项目来讲还没有完成,为了让我们的代码能够完全正确的工作,我们还需要对项目进行测试。
因此,我们之前差不多为yabe的模型层功能书写的单元测试,同时确信博客引擎的核心功能差不多进行了完好的测试,然而关于一个web应用程序来讲模型层只是其中的一部分,我们还需要确定web接口能否按预期的目标一样正常工作。
也确实是讲还需要测试yabe博客引擎的操纵器层,甚至需要对UI自身进行测试,比如我们的JavaScript代码。
测试操纵器部分
Play提供了一种功能,确实是使用JUnit来直截了当测试应用程序的操纵器。
我们把这些测试叫做‘功能性测试’,这是因为我们打算测试web应用程序的完整功能。
差不多上,一个功能性测试将直截了当调用Play的ActionInvoker,和一个HTTP要求相似。
因此我们需要给出一个HTTP方法、一个URI和多个HTTP参数。
Play之后会路由这些要求,调用相应的action,同时回发到填写的响应(filledresponse)。
之后,你就能够对之进行分析,以检查响应内容是否你所预期的。
importorg.junit.*;
importplay.test.*;
importplay.mvc.*;
importplay.mvc.Http.*;
importmodels.*;
publicclassApplicationTestextendsFunctionalTest{
@Test
publicvoidtestThatIndexPageWorks(){
Responseresponse=GET("/");
assertIsOk(response);
assertContentType("text/html",response);
assertCharset("utf-8",response);
}
}
现在看,它依旧一个标准的JUnit测试。
请注意,在那个地点我们使用Play的FunctionalTest超类,要紧是为了得到所有可用的工具。
那个测试只对应用程序的主页进行了测试(/URL渲染一个HTML响应,以‘200OK’作为状态代码)。
接下来,我们将检查治理区域(administrationarea)的安全工作能否正常工作。
在ApplicationTest.java里添加下面那个新测试:
…
@Test
publicvoidtestAdminSecurity(){
Responseresponse=GET("/admin");
assertStatus(302,response);
assertHeaderEquals("Location","/login",response);
}
…
现在,用playtest命令把yabe应用程序运行于测试模式,打开,选择ApplicationTest.java测试并运行。
是绿色的吗?
因此!
通过这种方式,我们能够对所有的应用程序功能性进行测试,但把这用于测试一个基于html的web应用程序时,这并不是最好的方式。
关于我们的博客引擎项目来讲,直截了当在真实的扫瞄器进行测试可能会更好。
这确实是play的‘Seleniumtests’测试要干的事。
这种基于“功能性测试”的JUnit仍旧专门有用,专门是用于测试一个返回非html响应(比如JSON或XML)的Webservices时。
书写Selenium测试代码
Selenium是一个专用于测试web应用程序的测试工具。
那个工具最酷的确实是Selenium承诺我们在一个扫瞄器里直截了当运行测试套件,由于它使用的是真实的扫瞄器,因此,我们能够确定测试通过后,项目就能够在生产环境下完美的运行。
一个Selenium测试套件确实是一个专门的html文件。
HTMLsyntaxrequiredbySelenium必须使用的HTML语句比较单调(使用HTML表格元素进行数据格式化显示),好消息是play将使用play模板引擎和一系列支持简单Selenium表示语法的标签来关心你生成这些元素)。
使用模板最有味的特点是你全然不需要‘staticscenarios’,同时能够使用play模板强大的功能(如循环、条件块)来书写更复杂的测试。
然而,你仍旧能够连续在模板里使用原始的HTMLSelenium语法,假如需要的话,还能够不记得特定的Selenium标签。
假如你使用多个用于生成testscenarios(比如SeleniumIDE)的Selenium工具中的一个,这将变得专门有味。
新创建的play应用程序的默认测试套件差不多包含了一个Selenium测试,打开yabe/test/Application.test.html文件:
*{YoucanuseplainSeleniumcommandsusingtheseleniumtag}*
#{selenium}
//Openthehomepage,andcheckthatnoerroroccurred
open('/')
waitForPageToLoad(1000)
assertNotTitle('Applicationerror')
#{/selenium}
运行那个测试应该可不能有任何咨询题。
它只打开了主页,并检测页面内容是否包含了‘Applicationerror’文本。
然而,和任何复杂的测试一样,在导航到应用程序并进行测试之前,你需要设置一系列众所周知的数据,我们因此需要重用fixture概念,同时在开始测试之前使用yabe/test/data.yml文件,#{fixture/}标签导入这些测试数据:
#{fixturedelete:
'all',load:
'data.yml'/}
#{selenium}
//Openthehomepage,andcheckthatnoerroroccurred
open('/')
waitForPageToLoad(1000)
assertNotTitle('Applicationerror')
#{/selenium}
另外一个重要的情况确实是我们要在测试启动时检查我们是否有一个最新的用户session。
那个session将储备在扫瞄器的临时cookie里,你应该在两个连续的测试运行操作期间保持同一个session,因此,让我们用一个特定的命令开始测试:
#{fixturedelete:
'all',load:
'data.yml'/}
#{selenium}
clearSession()
//Openthehomepage,andcheckthatnoerroroccurred
open('/')
waitForPageToLoad(1000)
assertNotTitle('Applicationerror')
#{/selenium}
运行那个测试,并确定没有错误发生,结果应该是绿色的。
接下来我们将书写专门专门的测试,测试打开主页后检查默认的博文是否显示出来:
#{fixturedelete:
'all',load:
'data.yml'/}
#{selenium'Checkhomepage'}
clearSession()
//Openthehomepage
open('/')
//Checkthatthefrontpostispresent
assertTextPresent('Aboutthemodellayer')
assertTextPresent('byBob,14Jun09')
assertTextPresent('2comments,latestbyGuest')
assertTextPresent('Itisthedomain-specificrepresentation')
//Checkolderposts
assertTextPresent('TheMVCapplication')
assertTextPresent('JustatestofYABE')
#{/selenium}
在那个地点,我们使用了标准的Selenium语法,它叫Selenese。
运行它(你能够运行于一个不同的扫瞄器窗口里)。
我们现在就能够测试评论窗体了,只需要添加一个#{selenium/}到模板里即可:
#{selenium'Testcomments'}
//Clickon'TheMVCapplicationpost'
clickAndWait('link=TheMVCapplication')
assertTextPresent('TheMVCapplication')
assertTextPresent('nocomments')
//Postanewcomment
type('content','Hello')
clickAndWait('css=input[type=submit]')
//Shouldgetanerror
assertTextPresent('nocomments')
assertTextPresent('Authorisrequired')
type('author','Me')
clickAndWait('css=input[type=submit]')
//Check
assertTextPresent('ThanksforpostingMe')
assertTextPresent('1comment')
assertTextPresent('Hello')
#{/selenium}
再次才能,哦,失败了!
那个地点有一个严峻的咨询题显现。
我们事实上不能正确测试captcha验证码机制,因此,我们必须搞一些欺诈手段。
在测试模式下,我们将验证任何代码作为一个正确的验证码。
我们明白当框架a.Weknowthatwe’reintestmodewhentheframeworkidistest.Solet’smodifythepostCommentactionintheyabe/app/controllers/Application.javaskipthisvalidationintestmode:
…
if(!
Play.id.equals("test")){
validation.equals(code,Cache.get(randomID)).message("Invalidcode.Pleasetypeitagain");
}
…
Nowjustmodifythetestcasetotypeanycodeinthetextfield,asis:
…
type('author','Me')
type('code','XXXXX')
clickAndWait('css=input[type=submit]')
…
Andnowrunthetestagain,itshouldwork.
Measuringcodecoverage
Ofcoursewehaven’twrittenallrequiredtestcasesfortheapplication.Butit’senoughforthistutorial.Nowinareal-worldproject,howcanweknowifwehavewrittenenoughtestcases?
Weneedsomethingcalled‘codecoverage’.
TheCoberturamodulegeneratescodecoveragereportsusingtheCoberturatool.Installthemoduleusingtheinstallcommand:
playinstallcobertura-{version}
Weneedtoenablethismoduleonlyfortestmode.Soaddthislinetotheapplication.conffile,andrestarttheapplicationintestmode.
#Importthecoberturamoduleintestmode
%test.module.cobertura=${play.path}/modules/cobertura
NowreopenthebrowserattheURL,selectalltestsandrunthem.Allshouldbegreen.
Whenalltestsarepassed,stoptheapplicationandcoberturawillthengeneratethecodecoveragereport.Youcanthenopentheyabe/test-result/code-coverage/index.htmlinyourbrowserandcheckthereport.
Ifyoustarttheapplicationagain,youcanalsoviewitat.
Asyouseewe’refarfromtestingalloftheapplication’scases.Agoodtestingsuiteshouldapproach100%,evenifitisofcoursenearlyimpossibletocheckallthecode.Typicallybecauseweoftenneedtohackintestmode,likewedidforthecaptcha.