(Translated by https://www.hiragana.jp/)
GitHub - qiniu/httptest: Qiniu httptest utilities
Skip to content
This repository has been archived by the owner on Mar 12, 2024. It is now read-only.

qiniu/httptest

Repository files navigation

httptest

LICENSE Build Status Go Report Card GitHub release Coverage Status GoDoc

Qiniu Logo

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 ふく务测试脚ほんかまち及实ようほどじょわが们定义了一个测试脚本的 DSL 语言。大体だいたいおこりらい这样てき

#为了让一套代码同时可以测试 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

命令めいれい详解

文法ぶんぽう

整体せいたい命令めいれい行文こうぶんほう为基础。一条指令由命令及命令参数构成。命令めいれい命令めいれいさんすう间以空白くうはくそらかくあるTAB)ぶんへだた。如果ぼう个参すうちゅう包含ほうがんそらかくある其他特殊とくしゅ,则可以:

  • よう \ 转义。如 '\ ' 表示ひょうじ ' '(そらかく),'\t' 表示ひょうじ TAB とうとう
  • よう '...' ある "..." 包含ほうがん。两者みやこまこと许出现 $(var) ある ${var} 形式けいしき表示ひょうじてき变量(这いちてん linux shell ゆう很大不同ふどう,详细见后ぶん智能ちのう变量” いち节)。们的别在于:'...' ちゅう支持しじよう \ 转义,也不支持しじ命令めいれい(见后ぶん命令めいれいいち节),现任なん内容ないようとうさく普通ふつう对待。所以ゆえん '\t|abc|' よう "..." らいおもて达必须用 "\\t\|abc\|"

类型けい

ざい linux shell てき命令めいれいぎょうちゅう所有しょゆうてき输入输出くし基本きほんじょうぼつゆう类型けい统可ごと。这いちてんわが们和 linux shell ゆう很大てき不同ふどうわが们的あし本有ほんゆうかん备的类型けい统。

わが支持しじ并仅支持しじ json 文法ぶんぽうしょ支持しじてき所有しょゆう类型。もと础类がた包括ほうかつ:number (ざい Go 语言ちゅう float64)、bool、string。复合类型包括ほうかつ array(ざい Go 语言さとめん slice,すう组)かず dictionary/object (ざい Go 语言ちゅう map/interface{})。とく别需要注意ようちゅういてきわが们的类型けい统里めんぼつゆう int 类型。null そら array,也不そら dictionary,而是そら object。

よし于我们采ようりょう命令めいれい行文こうぶんほう所以ゆえんひょう达类がたつね规文ほうゆう一定いっていてき异。如 200、'200'、"200" 表示ひょうじどういち个东西にし:number 类型てき 200。おもて达字くし "200" 必须よう '"200"' あるもの ""200""。

上面うわつら样例ちゅうてき

'[{"code": $(code1)}, {"code": 612}]'

いち个 array,如果わが们用紧凑文法ぶんぽううつし,避免にんなんてき空白くうはく以写なり这样:

[{"code":$(code1)},{"code":612}]

当然とうぜんわが们建议表达复あい类型てき时候,つきりょう还是よう '...' らいうつし,以保证可阅读せい

另外,こう虑到 json ただゆう如下这些语法单元:

  • 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"'

另外,对于些明确接受せつじゅ string さんすうてき指令しれい,也可以省略しょうりゃく '"..."' 这样てきそところも

智能ちのう变量

かず linux shell 类似,わが们也支持しじ $(var) ある ${var} 格式かくしきてき变量。ただし,$(var) 并不ぞう linux shell 样,ざい命令めいれいぎょう词法分析ぶんせき阶段就被处理掉了,它是ほん DSL 代表だいひょう变元てき语法成分せいぶん "..." つねくしてき语法成分せいぶん类似。另外,ゆかり于我们存在そんざい类型けい统,所以ゆえん $(var) おもて达的いちだんぶんほん,而是一个可能是任意类型的 object。这带らい这样いち些差异:

  • 支持しじ dictionary/object、array てき member なり员获取操作そうさ如对 dictionary 以做 $(a.b.c) 形式けいしきてき member 访问。对于 array,论上应该支持しじ $(a[1]) 这种形式けいしき过目まえわが们用てき $(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 转义方法ほうほう也完ぜん不同ふどうただし这个细节经常容易よういゆるがせりゃく)。

ひきはい(match)

这几乎是这套 DSL ちゅうさい核心かくしんてき概念がいねんさく为一门语ごとゆう变量,自然しぜんかいゆう赋值てき概念がいねんざい这里てき确有实现赋值てき能力のうりょくただし它不さけべ赋值,而是さけべひきはいさきれい

match $(a.b) 1
match $(a.c) '"hello"'

这个れいてき结果とくいたりょういち个变りょう a,其值为 {"b": 1, "c": "hello"}。

いた现在为止,你看いたてき match ぞう赋值てきいちめんただし不能ふのう对已经绑ていりょう特定とくてい值的变量さいつぎ不同ふどうてき值:

match $(a.b) 1
match $(a.b) 1		#以匹はいいん为$(a.b)てき值的确为1
match $(a.b) 2		#しつ败,12相等そうとう

match 语句以很复杂,如:

match '{"c": {"d": $(d)}}' '{"c": {"d": "hello", "e": "world"}, "f": 1}'

一般いっぱん,match 命令めいれいてき文法ぶんぽう为:

match <ExpectedObject> <SourceObject>

其中 <SourceObject> ちゅう不能ふのう现未绑定てき变量。<ExpectedObject> ちゅう则允许存在そんざい绑定てき变量。<ExpectedObject> <SourceObject> 必完ぜん一致いっちただしこれ <ExpectedObject> 中出なかいで现的,ざい <SourceObject> 中也ちゅうや必须现,也就要求ようきゅうしゅう关系(<ExpectedObject> これ <SourceObject> てきしゅう)。<ExpectedObject> ちゅうぼう个变りょう如果还未绑定,则按あきら对应てき <SourceObject> てき值进ぎょう绑定;如果变量やめ经绑じょう,则两边的值必须是ひきはいてき

ささえ撑我们整个 DSL てきもとせきせいひきはい文法ぶんぽう。这里你可以把所有しょゆう支持しじてき命令めいれいなり bool ひょう达式,如果かえしかい true 则成功せいこうかえしかい false 则失败。わが们看一开始你看到的例子的片段:

ret 298
json '[{"code": $(code1)}, {"code": 612}]'

它表达的含义要求ようきゅうかえしかいつつみてき StatusCode = 298,しかきさきかえしかいてき Response Body 必须のう够匹はい '[{"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|

かず linux shell しょうわが们多りょういち个子命令めいれい语法:|...|。这没ゆう别的图,纯粹为了 Go 语言てき友好ゆうこうせい(linux 风格てき命令めいれいざい Go さとめんひょう达需ようとく别费劲)。

わが们样れいちゅうてき两个命令めいれい env base64 みやこただしかえしかい string 类型。ただしさく为我们 DSL てきいち部分ぶぶん命令めいれいどう样可以返かいわが们类がたけい统中てき任意にんい类型。所以ゆえんはら则上わが们的命令めいれい如同变量いち样,ゆう上下じょうげ文相ぶんしょう关的 marshal 需求,如:

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)}

也就为每个子命令めいれいさと生成せいせい一个自动变量,这样就可以让上下じょうげ文相ぶんしょう关的 marshal 能力のうりょく,统一いたゆかり智能ちのう变量” らい支持しじ

HTTP API 测试

请求つつみ

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>

あんれい支持しじ

一般测试案例框架都有选择性执行某个案例、个案れいどもとおる setUp、tearDown 这样てき启动终止だい码。わが们 DSL 也支持しじ,如下:

#だい码片だん1
...

case testCase1
#だい码片だん2
...

case testCase2
#だい码片だん3
...

tearDown
#だい码片だん4
...

这段だい码里めん,“だい码片だん1” はた认为 setUp だい码,“だい码片だん4” tearDown だい码,所有しょゆう testCase 开始ぜん都会とかい执行いちへんだい码片だん1”,退出たいしゅつぜん执行いちへんだい码片だん4”。まい个 case 不用ふよううつし end 语句,ぐういたしもいち个 case あるものぐういた tearDown 就代表だいひょう该 case 结束。

运算能力のうりょく

目前もくぜん,这套 DSL てき运算能力のうりょく较有げんてき基本きほんじょうただのう做字くし拼接(concat)。如下:

match $(c) '"Hello $(a), $(b)!"'

如果わが希望きぼう做复杂运さんわが设想未来みらいゆう可能かのうどおり支持しじ calc 这样てき命令めいれいれい如:

match $(g) `calc max($(a), $(b), $(c)) + sin($(d)) + $(e)`

实现いちcalc 并不复杂,ざい C++ ちゅうよう TPL ただじゅうふん钟的事情じじょうただしざい Go 语言さとめん怎么做还ぼつゆうとく别去研究けんきゅう)。

こう虑尽可能かのう利用りよう现有资源てき话,わが们可以考虑内はま lua らい实现 calc 支持しじ如:

match $(g) `calc math.max($(a), $(b), $(c)) + math.sin($(d)) + $(e)`

参考さんこう

ゆうりょう calc 事情じじょう就更ゆう意思いしりょうわが们还直接ちょくせつよう calc 命令めいれい断言だんげん如:

calc $(a) < $(b)

ざい calc 外面がいめん套任なん指令しれいゆかりcalc かえしかい false ある true,而基于前めんかえしかい true 表示ひょうじ成功せいこうかえしかい false 表示ひょうじしつ败的げん则,这个指令しれい直接ちょくせつ就是断言だんげん当然とうぜん为了友好ゆうこうわが们可以搞个别てき名字みょうじ

assert $(a) < $(b)

りゅうほどひかえせい

ひとしひとし,难道わが们真よう做一个图灵完备的语言?上面うわつらてき运算能力のうりょくてき讨论やめ经有てんだつ离需もとめりょうさき实际使用しようちゅう检验吧),わが们就此打じゅう吧。