httprunner 3.x學習20 - jmespath取值特殊字符問題解決


前言

jmespath在取值的時候,遇到一些特殊的字符處理起來會比較麻煩。
httprunner3.x提取和校驗結果都是用jmespath取值,本篇總結幾個常見的問題

使用案例

訪問/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]

extract 提取結果

提取表達式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()

暫時遇到的問題就這些,可能還有其它問題

網易雲課程地址


點我 ->立即報名


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM