Revel测试需启用testrunner模块并继承revel.TestSuite,否则请求404或panic;路由未注册、控制器未导出、路径不匹配是404主因;断言前应打印响应体并用Assertf校验内容。

Revel 框架自带的测试能力足够跑通接口自检,但默认配置不启用、结构不规范时容易卡在 TestSuite 初始化或请求 404,根本原因是测试服务器没真正启动或路由未加载。
testrunner 模块必须显式启用
Revel 的测试不是靠 go test 原生运行的,它依赖独立的 testrunner 模块提供内嵌 HTTP 服务和请求代理。不启用就等于没接通被测应用。
- 在
conf/app.conf中必须添加:module.testrunner = github.com/revel/revel/modules/testrunner - 确保该模块已
go get安装,且版本与当前 Revel 主版本兼容(例如 Revel v0.29 要配 testrunner v0.29) - 若用
revel test命令报错 “no testrunner module found”,说明模块路径写错或未下载
测试套件必须继承 revel.TestSuite 并正确初始化
只定义 struct 不够,revel.TestSuite 内部持有 *http.Client 和模拟的 server 实例,缺失继承会导致 t.Get("/") 直接 panic 或返回空响应。
- 结构体必须嵌入:
type AppTest struct{ revel.TestSuite },不能只是字段名相同 -
Before()中不要手动 newhttp.Client,框架已初始化好;如需定制(如加 timeout),应改写t.Client.Timeout = 5 * time.Second - 所有测试方法名必须以
Test开头,且接收指针 receiver:func (t *AppTest) TestLoginEndpoint() { ... }
请求路径必须匹配真实路由,而非文件路径
t.Get("/login") 发的是对运行中 Revel 应用的 HTTP 请求,不是读取文件。如果返回 404,90% 是路由未注册或控制器方法未导出。
- 检查
app/routes是否有对应行,例如:GET /login App.Login - 确认
app/controllers/app.go中Login()方法首字母大写(Go 导出规则) - 避免在测试里写
t.Get("/app/login")—— Revel 默认不带/app前缀,除非你显式配置了app.name = "app"且启用了子路径模式 - 调试时可在
Before()加println("Routes loaded:", revel.BuiltInController.Routes)看实际注册列表
断言失败时不打印响应体是最大盲区
t.AssertOk() 只检查状态码,但多数接口问题出在 JSON body 错误或字段缺失。默认不输出响应内容,导致你反复改参数却不知哪条字段没对上。
- 在断言前加日志:
fmt.Printf("Response body: %s\n", string(t.ResponseBody)) - 用
t.Assertf()替代原始assert,例如:t.Assertf(len(t.ResponseBody) > 0, "empty response body") - 若需校验 JSON 字段,建议引入
github.com/stretchr/testify/assert,配合json.Unmarshal解析后断言,比纯字符串匹配更可靠
真正卡住人的从来不是语法,而是测试进程以为自己连上了应用,其实 testrunner 根本没拉起服务,或者路由表是空的——这两个点不验证,写再多 TestXXX 方法也只会返回空响应或 panic。











