Deprecated: This project is moved to github.com/goplus/yap/ytest (It's no longer a DSL, but a Go+ classfile, which makes it even more powerful).
go get -u github.com/qiniu/httptest
演 讲稿:七 牛 如何 做HTTP服 务测试?文字 整理 稿 :七 牛 如何 做HTTP服 务测试?
这是
#为了让一套代码同时可以测试 Stage 环境和 Product 环境,我 们推荐将 Host、AK/SK 作 为环境 变量传入
#同 时也避免了 AK/SK 这样敏感 内容 进入代 码库
match $(env) `envdecode QiniuTestEnv`
auth qboxtest `qbox $(env.AK) $(env.SK)`
host rs.qiniu.com $(env.RSHost)
post http://rs.qiniu.com/delete/`base64 Bucket:Key`
auth qboxtest
#发起请求,并开始 检查结果
ret 200
post http://rs.qiniu.com/batch
auth qboxtest
match $(ekey1) |base64 Bucket:Key|
match $(ekey2) |base64 Bucket2:Key2|
json '{
"op": ["/delete/$(ekey1)", "/delete/$(ekey2)"]
}'
#发起请求,并开始 检查结果
ret 200
post http://rs.qiniu.com/batch
auth qboxtest
form op=/delete/`base64 Bucket:Key`&op=/delete/`base64 Bucket:NotExistKey`
#发起请求,并开始 检查结果
ret 298
json '[{"code": $(code1)}, {"code": 612}]'
match $(code1) 200
参 见:qiniutest
用 \ 转义。比 如 '\ '表示 ' '(空 格 ),'\t'表示 TAB字 符 ,等 等 。用 '...'或 "..."包含 。两者都 允 许出现$(var) {var}或 $形式 表示 的 变量(这一 点 和 linux shell有 很大不同 ,详细见后文 “智能 变量”一 节)。他 们的区 别在于:'...'中 不 支持 用 \ 转义,也不支持 子 命令 (见后文 “子 命令 ”一 节),出 现任何 内容 都 当 作 普通 字 符 对待。所以 '\t|abc|'
用 "..."来 表 达必须用"\\t\|abc\|"
。
'[{"code": $(code1)}, {"code": 612}]'
[{"code":$(code1)},{"code":612}]
另外,
- array/dictionary/object/string:
[...]
,{...}
,null
,"..."
- bool:
true
,false
- number:
0..9
,-
- var:
$(...)
//我 们扩展 的 语法
所有 a..z或 A..Z 开头的 非 true
,false
,null
文 本 ,被 认为是 合法 的 json string。
也就
http://rs.qiniu.com/batch
'"http://rs.qiniu.com/batch"'
另外,对于
支持 dictionary/object、array的 member成 员获取操作 。比 如对 dictionary可 以做$(a.b.c) (a[1]) 这种形式 的 member 访问。对于 array,理 论上应该支持 $形式 ,不 过目前 我 们用的 是 $(a.1)。表 达a[2].b[3].c
可 以用 $(a.2.b.3.c)表示 。- 变量
智能 marshal。在 不同 的 场景下 ,变量的 marshal 结果会 有 差 异。所以 变量 marshal需要 上下 文 ,而不是 简单的 字 符 串 替 换。比 如 http://rs.qiniu.com/delete/$(ekey)和 {"delete":$(ekey)} 这两个地方 ,$(ekey)的 marshal 结果有 很大的 差 别。除 了 出 现在 json里 面 的 $(ekey)需要 用 "..."括 起 来 ,而 url中 不 需要 这样的 显著差 别外,对于特殊 字 符 的 escape 转义方法 也完全 不同 (但 是 这个细节经常容易 被 忽 略 )。
这几乎是这套 DSL
match $(a.b) 1
match $(a.c) '"hello"'
这个
match $(a.b) 1
match $(a.b) 1 #可 以匹配 ,因 为$(a.b)的 值的确为1
match $(a.b) 2 #失 败,1和 2不 相等
match 语句
match '{"c": {"d": $(d)}}' '{"c": {"d": "hello", "e": "world"}, "f": 1}'
match <ExpectedObject> <SourceObject>
其中 <SourceObject>
<ExpectedObject>
<ExpectedObject>
<SourceObject>
<ExpectedObject>
<SourceObject>
<ExpectedObject>
<SourceObject>
<ExpectedObject>
<SourceObject>
ret 298
json '[{"code": $(code1)}, {"code": 612}]'
它表达的含义'[{"code": $(code1)}, {"code": 612}]'
,Content-Type 则必须为 application/json
。它等价于:
ret #不 带参数 的 ret 仅仅发起请求,并将返 回 包 存 储在 $(resp) 变量中 ,不 做任何 匹 配
match 298 $(resp.code)
match '["application/json"]' $(resp.header.Content-Type)
match '[{"code": $(code1)}, {"code": 612}]' $(resp.body)
如同 linux shell
host rs.qiniu.com `env QiniuRSHost`
match $(ekey1) |base64 Bucket:Key|
match $(ekey2) |base64 Bucket2:Key2|
|...|
。这没
env
base64
post http://rs.qiniu.com/delete/`base64 Bucket:Key`
match $(foo) {"ekey":`base64 Bucket:Key`}
为了达到这样
match $(__auto_var_1) `base64 Bucket:Key`
post http://rs.qiniu.com/delete/$(__auto_var_1)
match $(__auto_var_2) `base64 Bucket:Key`
match $(foo) {"ekey":$(__auto_var_2)}
也就
请求
req <Method> <Url> #可 以简写 为 post <Url> 或 get <Url> 或 delete <Url>
auth <AuthInterface>
header <Key1> <Value1>
header <Key2> <Value2>
body <BodyType> <Body> #可 以简写 为 form <FormBody> 或 json <JsonBody>
ret <Code> #参 数 可 不 指定 。不 带参数 的 ret 仅仅发起请求,并将返 回 包 存 储在 $(resp) 变量中
header <Key1> <Value1>
header <Key2> <Value2>
body <BodyType> <Body> #可 以简写 为 json <JsonBody>
一般测试案例框架都有选择性执行某个案例、
#代 码片段 1
...
case testCase1
#代 码片段 2
...
case testCase2
#代 码片段 3
...
tearDown
#代 码片段 4
...
这段
match $(c) '"Hello $(a), $(b)!"'
如果calc
这样
match $(g) `calc max($(a), $(b), $(c)) + sin($(d)) + $(e)`
实现calc
并不复杂,
match $(g) `calc math.max($(a), $(b), $(c)) + math.sin($(d)) + $(e)`
- https://github.com/aarzilli/golua
- https://github.com/stevedonovan/luar (
基 于 golua的 进一 步 包装 )
calc
calc
calc $(a) < $(b)
calc
calc
false
true
,而基于前true
false
assert $(a) < $(b)