Go Web开发之Revel - 测试
2013-01-09 09:44 Danny.tian 阅读(2445) 评论(0) 编辑 收藏 举报Revel提供了一个测试框架,这使得在应用程序中写和运行测试函数变得很容易.
skeleton应用程序带有一个简单的测试来帮助我们测试.
概要
测试保存在tests目录
corp/myapp app/ conf/ public/ tests/ <----
一个简单的测试看起来像下面这样:
type ApplicationTest struct { rev.TestSuite } func (t ApplicationTest) Before() { println("Set up") } func (t ApplicationTest) TestThatIndexPageWorks() { t.Get("/") t.AssertOk() t.AssertContentType("text/html") } func (t ApplicationTest) After() { println("Tear down") }
上面的示例代码展示了几件事:
- 一个测试工具是任意嵌入rev.TestSuite的struct
- 如果存在 Before() 和 After() 方法, 它们将在每一个测试方法的前后被调用
- rev.TestSuite 为发布请求到应用程序和断言响应信息提供帮助
- 一个断言失败产生一个panic, 它将被harness捕获
你可以已两种方式运行测试:
- 交互式的, 从你的浏览器运行在测试部署时很有帮助
- 非交互式的, 从命令行运行对结合一个持续集成很有帮助
开发一个测试工具
创建一个你自己的测试工具, 定义一个嵌入 rev.Testsuite的struct, 它提供一个HTTP客户端和许多帮助方法来发出请求到你的应用程序.
type TestSuite struct { Client *http.Client Response *http.Response ResponseBody []byte } // Some request methods func (t *TestSuite) Get(path string) func (t *TestSuite) Post(path string, contentType string, reader io.Reader) func (t *TestSuite) PostForm(path string, data url.Values) func (t *TestSuite) MakeRequest(req *http.Request) // Some assertion methods func (t *TestSuite) AssertOk() func (t *TestSuite) AssertContentType(contentType string) func (t *TestSuite) Assert(exp bool) func (t *TestSuite) Assertf(exp bool, formatStr string, args ...interface{})
全部的请求方法表现相似:
- 它们接收一个路径(例如: /users/)
- 它们发出请求到应用程序服务器
- 它们把响应存储了Response属性中
- 它们读取全部的响应body到ResponseBody属性
如果开发人员希望使用自定义的HTTP Client代替默认的 http.DefaultClient, 它们应该在Before()方法里面替换它.
如果它们没有满足条件全部断言都将产生一个panic. 全部的panic被测试harness捕获并展示为错误.
运行一个测试工具
为了运行任何测试, testrunner模块必须被激活. 添加下面一行代码到 app.conf 以保证激活它
module.testrunner = github.com/robfig/revel/modules/testrunner
完成上面之后测试就被运行了(交互式或非交互式)
运行交互式的测试
利用Revel的热编译功能, 一个交互式的测试运行器用来提供给快速编辑刷新的循环工作.
例如, 开发人员在他们的浏览器加载 /@tests
然后他们添加一个测试方法
func (t ApplicationTest) TestSomethingImportant() { t.Get("/") t.AssertOk() t.AssertContentType("text/xml") }
刷新页面将看到新的测试方法
运行这个测试
它没有正常工作. 我们来修复这个问题替换 “text/xml” 为 “text/html”, 刷新浏览器:
成功.
运行非交互式的测试
Revel 命令行工具 提供了一个 test 命令, 它运行全部的应用程序在命令行工具中运行测试.
示例如下:
$ revel test github.com/robfig/revel/samples/booking dev ~ ~ revel! http://robfig.github.com/revel ~ INFO 2012/11/09 19:21:02 revel.go:237: Loaded module testrunner Open DB Listening on port 9000... INFO 2012/11/09 19:21:06 test.go:95: Testing Booking example (github.com/robfig/revel/samples/booking) in dev mode Go to /@tests to run the tests. 1 test suite to run. ApplicationTest PASSED 0s All Tests Passed.
在控制台只有一个简单的 PASSED/FAILED 概要通过测试工具来显示. 这个工具写入更多的结果到文件系统:
$ cd src/github.com/robfig/revel/samples/booking $ find test-results test-results test-results/app.log test-results/ApplicationTest.passed.html test-results/result.passed
它写入了3个不同的东西:
- 应用程序的stdout和stderr被重定向到 app.log
- 一个HTML文件每个测试工具都写入描述测试的通过和失败的信息
- 要么result.passed要么result.failed被写入, 依赖于总体是否成功
这里有两个集成这个到持续构建的建议机制
- 检查返回代码, 0表示成功非0另外
- 运行后需要result.success或者不允许result.failed.
实现说明
Revel做了什么:
- 为嵌套TestSuite类型扫描测试源代码
- 在生成main.go时设置rev.TestSuites变量到那些类型的列表
- 使用反射在TestSuite类型上查找全部的以Test开头的方法并调用它们来运行测试
- 从bugs或失败的断言中捕获panics并显示有帮助的错误信息
开发区域
可以使用以下方式改进测试框架
- Fixtures来填充测试数据
- 记录器写入一个文件(替换 stderr / stdout )也应该被重定向到 test-results/app.log
至此结束