访问/api/test/demo接口,接口返回如下
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
"code":0,
"msg":"成功success!",
"data":[
"age":20,
"create_time":"2019-09-15",
"id":1,
"mail":"283340479@qq.com",
"name":"yoyo",
"sex":"M"
"age":21,
"create_time":"2019-09-16",
"id":2,
"mail":"123445@qq.com",
"name":"yoyo111",
"sex":"M"
validate 校验
1.提取data数据中name的值为yoyo的邮箱,并校验结果是:283340479@qq.com
2.提取data数据组中,年龄大于20的结果,并校验结果的数量是:1
先看第一个问题,有[]字符的时候
config:
name: logincase
base_url: http://127.0.0.1:8000
variables: {}
teststeps:
name: step1 login
request:
url: /api/test/demo
method: GET
validate:
- eq: [status_code, 200]
- eq: [body.data[?name=='yoyo'].mail, ["283340479@qq.com"]]
运行后结果 :expected ',' or ']', but got '['
D:\demo>hrun demo.yml
2021-08-24 18:56:11.154 | INFO | httprunner.make:__make:512 - make path: D:\demo\demo.yml
2021-08-24 18:56:11.158 | ERROR | httprunner.loader:_load_yaml_file:36 - YAMLError:
file: D:\202108kecheng\demo\demo.yml
error: while parsing a flow sequence
in "D:\202108kecheng\demo\demo.yml", line 13, column 15
expected ',' or ']', but got '['
in "D:\202108kecheng\demo\demo.yml", line 13, column 25
2021-08-24 18:56:11.159 | WARNING | httprunner.make:__make:530 - Invalid test file: D:\demo\demo.yml
FileFormatError:
2021-08-24 18:56:11.160 | INFO | httprunner.make:format_pytest_with_black:170 - format pytest cases with black ...
No Path provided. Nothing to do 😴
2021-08-24 18:56:11.427 | ERROR | httprunner.cli:main_run:49 - No valid testcases found, exit 1.
Sentry is attempting to send 0 pending error messages
Waiting up to 2 seconds
Press Ctrl-Break to quit
主要原因是,表达式 body.data[?name=='yoyo'].mail
里面有个 ] 符合,刚好跟httprunner3读取yaml文件语法冲突了
解决办法可以把表达式当一个字符串:"body.data[?name=='yoyo'].mail"
validate:
- eq: [status_code, 200]
- eq: ["body.data[?name=='yoyo'].mail", ["283340479@qq.com"]]
管道符 |
上面 jmespath 表达式 body.data[?name=='yoyo'].mail
取出来的值是list: ["283340479@qq.com"]
如果我们想取出字符串,拿字符串去校验可以继续取值,在结果中继续取值用管道符 |
,然后下标取出第一个
validate:
- eq: [status_code, 200]
- eq: ["body.data[?name=='yoyo'].mail|[0]", "283340479@qq.com"]
如果jmespath表达式过滤条件有数字类型的,判断age>20
validate:
- eq: [status_code, 200]
- eq: ["body.length(data[?age>20])", 1]
此时会报错:ParseError,表达式不合法
E jmespath.exceptions.ParseError: invalid token: Parse error at column 22, token "20" (NUMBER), for expression:
E "body.length(data[?age>20])"
关于数字类型,需要在数字上加特殊字符 `20`
validate:
- eq: [status_code, 200]
- eq: ["body.data[?name=='yoyo'].mail|[0]", "283340479@qq.com"]
- eq: ["body.length(data[?age>`20`])", 1]
提取表达式body.data[?name=='yoyo'].mail|[0]
的结果,用extract关键字
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
config:
name: logincase
base_url: http://127.0.0.1:8000
variables: {}
teststeps:
name: step1 login
request:
url: /api/test/demo
method: GET
extract:
mail: body.data[?name=='yoyo'].mail|[0]
validate:
- eq: [status_code, 200]
- eq: ["body.data[?name=='yoyo'].mail|[0]", "283340479@qq.com"]
- eq: ["body.length(data[?age>`20`])", 1]
这样直接提取会遇到一个问题,转成py代码的时候,单引号语法冲突了
Step(RunRequest("step1 login")
.get("/api/test/demo")
.extract()
.with_jmespath('body.data[?name=='yoyo'].mail|[0]', 'mail')
但是jmespath 里面字符串只能用单引号,不能改成 body.data[?name=="yoyo"].mail|[0]
如果改成双引号,虽然语法上没有问题,但是提取不到结果: extract mapping: {'mail': None}
此处修改,可以用转义字符,在yaml文件中把单引号转成\'
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
config:
name: logincase
base_url: http://127.0.0.1:8000
variables: {}
teststeps:
name: step1 login
request:
url: /api/test/demo
method: GET
extract:
mail: body.data[?name==\'yoyo\'].mail|[0]
validate:
- eq: [status_code, 200]
- eq: ["body.data[?name=='yoyo'].mail|[0]", "283340479@qq.com"]
- eq: ["body.length(data[?age>`20`])", 1]
这样就可以达到效果了,运行日志可以看到取到了mail extract mapping: {'mail': '283340479@qq.com'}
转成对应的py脚本
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseDemo(HttpRunner):
config = Config("logincase").base_url("http://127.0.0.1:8000")
teststeps = [
Step(
RunRequest("step1 login")
.get("/api/test/demo")
.extract()
.with_jmespath("body.data[?name=='yoyo'].mail|[0]", "mail")
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.data[?name=='yoyo'].mail|[0]", "283340479@qq.com")
.assert_equal("body.length(data[?age>`20`])", 1)
if __name__ == "__main__":
TestCaseDemo().test_start()
暂时遇到的问题就这些,可能还有其它问题
网易云课程地址