首页
学习
活动
专区
圈层
工具
发布

测试开发进阶(三十三)

局部变量

代码语言:javascript
复制
name: 登录接口
variables:
    username: ${ENV(USERNAME)}
    password: ${ENV(PASSWORD)}
request:
    url: http://127.0.0.1:8000/user/login/
    method: POST
    headers:
        Content-Type: "application/json"
    json:
        username: $username
        password: $password
validate:
    - eq: ["status_code", 200]
extract:
    - uname: content.username

可以修改 variables定义变量,导入环境变量作为值

request中可以使用 $变量名来获取 variables区域下的变量

调用函数

可以调用 debugtalk.py中的函数

例如在该文件中添加

代码语言:javascript
复制
def get_user_agent():
    user_agents = ['Mozilla/5.0 AAA', 'Mozilla/5.0 BBB', 'Mozilla/5.0 CCC']
    return random.choice(user_agents)
代码语言:javascript
复制
name: 登录接口
variables:
    username: ${ENV(USERNAME)}
    password: ${ENV(PASSWORD)}
request:
    url: http://127.0.0.1:8000/user/login/
    method: POST
    headers:
        Content-Type: "application/json"
        User-Agent: ${get_user_agent()}
    json:
        username: $username
        password: $password
validate:
    - eq: ["status_code", 200]

使用 ${get_user_agent()}

这样就可以动态的使用 User-Agent

校验

可以用的响应属性:

  • available
  • response
  • status_code
  • cookies
  • elapsed
  • headers
  • content
  • text
  • json
  • encoding
  • ok
  • reason
  • url
代码语言:javascript
复制
- eq: ["headers.Content-Type", "application/json"]
代码语言:javascript
复制
- {check: "headers.Content-Type",comparator: "eq",expect: "application/json"}

上面两种写法效果一致

  • check:指定断言哪一个字段(实际值)

python3.7/site-packages/httprunner/built_in.py

  • comparator:指定断言的规则
  • eq 等于
  • lt小于
  • lte
  • gt大于
  • gte
  • str_eq
  • len_eq长度等于
  • len_gt
  • contains 包含
代码语言:javascript
复制
"""
built-in comparators
"""
def equals(check_value, expect_value):
    assert check_value == expect_value

def less_than(check_value, expect_value):
    assert check_value < expect_value

def less_than_or_equals(check_value, expect_value):
    assert check_value <= expect_value

def greater_than(check_value, expect_value):
    assert check_value > expect_value

def greater_than_or_equals(check_value, expect_value):
    assert check_value >= expect_value

def not_equals(check_value, expect_value):
    assert check_value != expect_value

def string_equals(check_value, expect_value):
    assert builtin_str(check_value) == builtin_str(expect_value)

def length_equals(check_value, expect_value):
    assert isinstance(expect_value, integer_types)
    assert len(check_value) == expect_value

def length_greater_than(check_value, expect_value):
    assert isinstance(expect_value, integer_types)
    assert len(check_value) > expect_value

def length_greater_than_or_equals(check_value, expect_value):
    assert isinstance(expect_value, integer_types)
    assert len(check_value) >= expect_value

def length_less_than(check_value, expect_value):
    assert isinstance(expect_value, integer_types)
    assert len(check_value) < expect_value

def length_less_than_or_equals(check_value, expect_value):
    assert isinstance(expect_value, integer_types)
    assert len(check_value) <= expect_value

def contains(check_value, expect_value):
    assert isinstance(check_value, (list, tuple, dict, basestring))
    assert expect_value in check_value

def contained_by(check_value, expect_value):
    assert isinstance(expect_value, (list, tuple, dict, basestring))
    assert check_value in expect_value

def type_match(check_value, expect_value):
    def get_type(name):
        if isinstance(name, type):
            return name
        elif isinstance(name, basestring):
            try:
                return __builtins__[name]
            except KeyError:
                raise ValueError(name)
        else:
            raise ValueError(name)

    assert isinstance(check_value, get_type(expect_value))

def regex_match(check_value, expect_value):
    assert isinstance(expect_value, basestring)
    assert isinstance(check_value, basestring)
    assert re.match(expect_value, check_value)

def startswith(check_value, expect_value):
    assert builtin_str(check_value).startswith(builtin_str(expect_value))

def endswith(check_value, expect_value):
    assert builtin_str(check_value).endswith(builtin_str(expect_value))

  • expect预期结果

数据驱动

testcases/login.yml

代码语言:javascript
复制
config:
    name: "登录接口测试"
    variables:
        device_sn: "ABC"
        username: ${ENV(USERNAME)}
        password: ${ENV(PASSWORD)}
    base_url: "http://127.0.0.1:8000"

teststeps:
-
    name: 登录
    api: api/login.yml
    validate:
        - eq: ["status_code", 200]

继承 api/login.yml会与本区域定义的 validate合并覆盖

一般api路径下的断言只进行基础类型的断言例如 status_code

testcases会进行其他的断言

方式一:使用yaml

testsuites/api_testsuite.yml

代码语言:javascript
复制
config:
    name: 接口测试套件
    base_url: "http://127.0.0.1:8000"

testcases:
-
    name: 登录接口
    testcase: testcases/login.yml
    parameters:
        # 方式一
        # 多个具有关联性的参数,需要将其定义在一起,并且采用短横线进行连接
        - title-username-password-status_code-contain_msg:
              - ["正常登录", "zhongxin", "123456", 200, "token"]
              - ["密码错误", "zhongxin", "1234567", 400, "non_field_errors"]
              - ["账号错误", "zhongxin11", "123456", 400, "non_field_errors"]
              - ["用户名为空", "", "123456", 400, "username"]
              - ["密码为空", "zhongxin", "", 400, "password"]

运行

代码语言:javascript
复制
$ hrun testsuites/api_testsuite.yml

查看报告

方式二:读取文件

新建一个csv文件

代码语言:javascript
复制
title,username,password,status_code,contain_msg
正常登录, zhongxin, 123456, 200, token
密码错误, zhongxin, 1234567, 400, non_field_errors
账号错误, zhongxin11, 123456, 400, non_field_errors
用户名为空, , 123456, 400, username
密码为空, zhongxin, , 400, password
代码语言:javascript
复制
- title-username-password-status_code-contain_msg: ${P(datas/accounts.csv)}

方式三:使用函数

debugtalk.py添加

代码语言:javascript
复制
def get_accounts():
    accounts = [
        {"title": "正常登录", "username": "zhongxin", "password": "123456", "status_code": 200, "contain_msg": "token"},
        {"title": "密码错误", "username": "zhongxin", "password": "1234567", "status_code": 400, "contain_msg": "non_field_errors"},
    ]
    return accounts
代码语言:javascript
复制
- title-username-password-status_code-contain_msg: ${get_accounts()}

使用py文件调用httprunner

代码语言:javascript
复制
from httprunner.api import HttpRunner

# 创建HttpRunner对象
# failfast:False 用例执行失败后不终止
runner = HttpRunner(failfast=False)
# 运行用例
# run方法支持如下参数
# yaml用例文件的路径
# 字典(用例的信息)
runner.run('/Users/zhongxin/Desktop/httprunner_learn/testcases/login.yml')
print(runner.summary)
下一篇
举报
领券