HttpRunner快速入门

    技术2024-12-13  15

    安装

    $ pip install httprunner==2.3.0

    搭建项目

    $ hrun --startproject demo Start to create new project: demo CWD: /Users/zhongxin/PycharmProjects/learn_httprunner created folder: demo created folder: demo/api created folder: demo/testcases created folder: demo/testsuites created folder: demo/reports created file: demo/api/demo_api.yml created file: demo/testcases/demo_testcase.yml created file: demo/testsuites/demo_testsuite.yml created file: demo/debugtalk.py created file: demo/.env created file: demo/.gitignore

    项目结构

    demo/api

    最小单元,单个接口的操作

    demo/testcases

    一个测试点,多个接口依次调用

    demo/testsuites

    测试套,执行多个测试点

    demo/reports

    测试报告存放路径

    demo/.env

    环境配置文件

    demo/debugtalk.py

    使用python代码进行一些自定义操作

    demo/.gitignore

    git 版本管理提交时忽略的文件或文件夹

    项目结构

    单个接口实例

    先写一个简单的接口

    import json from flask import Flask, request, jsonify app = Flask(__name__) right_u_p = {     "username": "测试游记",     "password": "123456" } @app.route('/login', methods=['POST']) def login():     data = json.loads(request.data.decode())     if data.get('username') == right_u_p['username'] and data.get('password') == right_u_p['password']:         return jsonify({"Data": "账号密码正确"}), 200     else:         return jsonify({"Data": "账号密码错误"}), 401 if __name__ == '__main__':     app.run()

    在demo/api中编写第一个登陆的接口测试login.yml

    name: 登陆接口 variables:     var1: value1     var2: value2 request:     url: http://127.0.0.1:5000/login     method: POST     headers:         Content-Type: "application/json"     json:         username: "测试游记"         password: "123456" validate:     - eq: ["status_code", 200]

    运行

    $ hrun /Users/zhongxin/PycharmProjects/learn_httprunner/demo/api/login.yml 单个接口

    运行报告

    运行报告

    运行详情

    查看详情

    使用环境变量

    修改demo/.env

    USERNAME=测试游记 PASSWORD=123456 name: 登陆接口 variables:     var1: value1     var2: value2 request:     url: http://127.0.0.1:5000/login     method: POST     headers:         Content-Type: "application/json"     json:         username: ${ENV(USERNAME)}         password: ${ENV(PASSWORD)} validate:     - eq: ["status_code", 200]

    定义全局变量

    name: 登陆接口 variables:     uname: "测试游记"     pwd: "123456" request:     url: http://127.0.0.1:5000/login     method: POST     headers:         Content-Type: "application/json"     json:         username: $uname         password: $pwd validate:     - eq: ["status_code", 200]

    定义方法

    在variables中定义

    使用方法

    使用$变量名

    调用python函数

    在demo/debugtalk.py中编写获取随机user_agent的函数

    def get_user_agent():     user_agent = [         "Mozilla/5.0 ce",         "Mozilla/5.0 shi",         "Mozilla/5.0 you",         "Mozilla/5.0 ji",     ]     return random.choice(user_agent)

    在login.yml中使用

    name: 登陆接口 variables:     uname: "测试游记"     pwd: "123456" request:     url: http://127.0.0.1:5000/login     method: POST     headers:         Content-Type: "application/json"         User-Agent: ${get_user_agent()}     json:         username: $uname         password: $pwd validate:     - eq: ["status_code", 200]

    base_url

    提取url路径

    name: 登陆接口 variables:     uname: "测试游记"     pwd: "123456" base_url: http://127.0.0.1:5000 request:     url: /login     method: POST     headers:         Content-Type: "application/json"         User-Agent: ${get_user_agent()}     json:         username: $uname         password: $pwd validate:     - eq: ["status_code", 200]

    validate

    查看httprunner的源码:./site-packages/httprunner/validator.py

    从get_uniform_comparator可以看出它支持的断言以及其简写方式

    def get_uniform_comparator(comparator):     """ convert comparator alias to uniform name     """     if comparator in ["eq", "equals", "==", "is"]:         return "equals"     elif comparator in ["lt", "less_than"]:         return "less_than"     elif comparator in ["le", "less_than_or_equals"]:         return "less_than_or_equals"     elif comparator in ["gt", "greater_than"]:         return "greater_than"     elif comparator in ["ge", "greater_than_or_equals"]:         return "greater_than_or_equals"     elif comparator in ["ne", "not_equals"]:         return "not_equals"     elif comparator in ["str_eq", "string_equals"]:         return "string_equals"     elif comparator in ["len_eq", "length_equals", "count_eq"]:         return "length_equals"     elif comparator in ["len_gt", "count_gt", "length_greater_than", "count_greater_than"]:         return "length_greater_than"     elif comparator in ["len_ge", "count_ge", "length_greater_than_or_equals", \         "count_greater_than_or_equals"]:         return "length_greater_than_or_equals"     elif comparator in ["len_lt", "count_lt", "length_less_than", "count_less_than"]:         return "length_less_than"     elif comparator in ["len_le", "count_le", "length_less_than_or_equals", \         "count_less_than_or_equals"]:         return "length_less_than_or_equals"     else:         return comparator

    查看返回信息中的字段

    name: 登陆接口 variables:     uname: "测试游记"     pwd: "123456" base_url: http://127.0.0.1:5000 request:     url: /login     method: POST     headers:         Content-Type: "application/json"         User-Agent: ${get_user_agent()}     json:         username: $uname         password: $pwd validate:     - eq: ["status_code", 200]     - eq: ["content.Data", "账号密码正确"]

    testcases

    为了测试连续多个步骤

    场景:登陆后获取项目信息

    修改接口代码

    import json from flask import Flask, request, jsonify app = Flask(__name__) right_u_p = {     "username": "测试游记",     "password": "123456" } @app.route('/login', methods=['POST']) def login():     data = json.loads(request.data.decode())     if data.get('username') == right_u_p['username'] and data.get('password') == right_u_p['password']:         return jsonify({"Data": "账号密码正确", "token": "123456"}), 200     else:         return jsonify({"Data": "账号密码错误"}), 401 @app.route('/projects') def project():     print(request.headers.get("Authorization"))     if request.headers.get("Authorization") == '123456':         return jsonify({"Data": []}), 200     else:         return jsonify({"Data": []}), 401 if __name__ == '__main__':     app.run()

    demo/api/get_project_list.yml

    name: 获取项目信息 variables:     token: "xxxxx" base_url: http://127.0.0.1:5000 request:     url: /projects     method: GET     headers:         Content-Type: "application/json"         Authorization: $token validate:     - eq: ["status_code", 200]

    demo/testcases/get_project.yml

    可以直接使用已经编写好的接口yaml文件当作步骤

    config:     name: "获取项目信息"     variables:         username: ${ENV(USERNAME)}         password: ${ENV(PASSWORD)}     base_url: "http://127.0.0.1:5000" teststeps: -     name: 登陆     api: api/login.yml     extract:         - token: content.token -     name: 获取项目列表信息     api: api/get_project_list.yml

    testsuites

    单个接口demo/api/login.yml

    name: 登陆接口 variables:     uname: "测试游记"     pwd: "123456" base_url: http://127.0.0.1:5000 request:     url: /login     method: POST     headers:         Content-Type: "application/json"         User-Agent: ${get_user_agent()}     json:         username: $uname         password: $pwd validate:     - eq: ["status_code", 200]     - eq: ["content.Data", "账号密码正确"]

    参数不固定的接口测试demo/testcases/login.yml

    缺少参数:

    title 标题

    uname 账号

    pwd 密码

    config:     name: "登陆接口配置"     base_url: "http://127.0.0.1:5000" teststeps: -     name: $title     api: api/login.yml     validate:         - eq: ["status_code", $status_code]         - eq: ["content.Data", $content_data]

    参数遍历的测试套demo/testsuites/login.yml

    使用直接写入

    config:   name: "接口套件" testcases:   - name: "登陆接口套件"     testcase: testcases/login.yml     parameters:       - title-uname-pwd-status_code-content_data:           - ["正常登陆","测试游记","123456",200,"账号密码正确"]           - ["账号错误","测试游记1","",401,"账号密码错误"]           - ["密码错误","测试游记","1234567",401,"账号密码错误"]           - ["账号为空","","1234567",401,"账号密码错误"]           - ["密码为空","测试游记","",401,"账号密码错误"] 测试报告

    使用csv

    新建demo/datas/account.csv

    title,uname,pwd,status_code,content_data 正常登陆,测试游记,123456,200,账号密码正确 账号错误,测试游记1,,401,账号密码错误 密码错误,测试游记,1234567,401,账号密码错误 账号为空,,1234567,401,账号密码错误 密码为空,测试游记,,401,账号密码错误 config:   name: "接口套件" testcases:   - name: "登陆接口套件"     testcase: testcases/login.yml     parameters:       - title-uname-pwd-status_code-content_data: ${P(datas/account.csv)}

    使用csv会出现str和int类型比较的问题,需要在demo/debugtalk.py编写代码解决

    命令行执行

    from httprunner.api import HttpRunner httpruner = HttpRunner() httpruner.run(r'/Users/zhongxin/PycharmProjects/learn_httprunner/demo/testsuites/login.yml') print(httpruner.summary)
    Processed: 0.024, SQL: 9