10.完整的应用程序测试
现在,我们已经结束了博客引擎的编码工作,但对项目来说还没有完成,为了让我们的代码能够完全正确的工作,我们还需要对项目进行测试。
当然,我们之前已经为yabe的模型层功能书写的单元测试,并且确信博客引擎的核心功能已经进行了完好的测试,但是对于一个web应用程序来说模型层只是其中的一部分,我们还需要确定web接口能否按预期的目标一样正常工作。也就是说还需要测试yabe博客引擎的控制器层,甚至需要对UI自身进行测试,比如我们的JavaScript代码。
测试控制器部分
Play提供了一种功能,就是使用JUnit来直接测试应用程序的控制器。我们把这些测试叫做‘功能性测试’,这是因为我们打算测试web应用程序的完整功能。乔任梁事件真相图片
基本上,一个功能性测试将直接调用Play的ActionInvoker,和一个HTTP 请求相似。因此我们需要给出一个HTTP方法、一个URI和多个HTTP参数。Play之后会路由这些请求,调用相应的action,并且回发到填写的响应(filled response)。之后,你就可以对之进行分析,以检查响应内容是否你所预期的。
接下来让我们书写第一个功能性测试代码,打开
yabe/test/ApplicationTest.java单元测试:
import org.junit.*;
st.*;
import play.mvc.*;
import play.mvc.Http.*;
import models.*;
public class ApplicationTest extends FunctionalTest {网络设置
@Test
public void testThatIndexPageWorks() {
Response response = GET("/");
assertIsOk(response);
assertContentType("text/html", response);
assertCharset("utf-8", response);
现在看,它还是一个标准的JUnit测试。请注意,在这里我们使用Play 的 FunctionalTest超类,主要是为了得到所有可用的工具。这个测试只对应用程序的主页进行了测试(/ URL渲染一个HTML响应,以‘200 OK’作为状态代码)。
接下来,我们将检查管理区域(administration area)的安全工作能否正常工作。在ApplicationTest.java里添加下面这个新测试:
@Test
public void testAdminSecurity() {
Response response = GET("/admin");
assertStatus(302, response);红豆糖水
assertHeaderEquals("Location", "/login", response);关于冬天的古诗句
现在,用play test命令把yabe应用程序运行于测试模式,打开
localhost:9000/@tests, 选择ApplicationTest.java测试并运行。
是绿的吗?
当然!通过这种方式,我们可以对所有的应用程序功能性进行测试,但把这用于测试一个基于html的web应用程序时,这并不是最好的方式。对于我们的博客引擎项目来说,直接在真实的浏览器进行测试可能会更好。这就是play的‘Selenium tests’测试要干的事。
这种基于“功能性测试”的JUnit仍旧很有用,特别是用于测试一个返回非html响应(比如JSON或XML)的Web services时。
书写Selenium测试代码
Selenium 是一个专用于测试web应用程序的测试工具。这个工具最酷的就是Selenium允许我们在一个浏览器里直接运行测试套件,由于它使用的是真实的浏览器,因此,我们可以确定测试通过后,项目就可以在生产环境下完美的运行。
一个Selenium测试套件就是一个特殊的html文件。HTML syntax required by Selenium必须使用的HTML语句比较单调(使用HTML表格元素进行数据
格式化显示),好消息是play将使用play模板引擎和一系列支持简单Selenium表示语法的标签来帮助你生成这些元素)。使用模板最有趣的特点是你根本不需要‘static scenarios’,并且可以使用play模板强大的功能(如循环、条件块)来书写更复杂的测试。
然而,你仍旧可以继续在模板里使用原始的HTML Selenium语法,如果需要的话,还可以忘记特定的Selenium标签。如果你使用多个用于生成test scenarios(比如Selenium IDE)的Selenium工具中的一个,这将变得非常有趣。
新创建的play应用程序的默认测试套件已经包含了一个Selenium测试,打开yabe/st.html文件:
*{ You can use plain Selenium commands using the selenium tag }* #{selenium}
// Open the home page, and check that no error occurred
open('/')
waitForPageToLoad(1000)
assertNotTitle('Application error')
#{/selenium}
运行这个测试应该不会有任何问题。它只打开了主页,并检测页面内容是否包含了‘Application error’文本。
然而,和任何复杂的测试一样,在导航到应用程序并进行测试之前,你需要设置一系列众所周知的数据,我们当然需要重用fixture概念,并且在开始测试之前使用yabe/l文件,#{fixture /}标签导入这些测试数据:
#{fixture delete:'all', load:'l' /}
青山知可子#{selenium}
// Open the home page, and check that no error occurred
open('/')
waitForPageToLoad(1000)
assertNotTitle('Application error')
#{/selenium}
另外一个重要的事情就是我们要在测试启动时检查我们是否有一个最新的用户session。这个session将存储在浏览器的临时cookie里,你应该在两个连续的测试运行操作期间保持同一个session,因此,让我们用一个特定的命令开始测试:
#{fixture delete:'all', load:'l' /}
#{selenium}
clearSession()
// Open the home page, and check that no error occurred
open('/')
waitForPageToLoad(1000)
张泉灵丈夫