美文网首页
httprunner学习实践(三)--变量和方法的使用

httprunner学习实践(三)--变量和方法的使用

作者: 陈凌川 | 来源:发表于2019-08-01 14:29 被阅读0次

序言

httprunner的使用和其中的一些概念在官方的文档中已经详细说明,写这个学习记录是为了记录下自己的学习历程,能够在今后快速的深入学习和实践。没有提及的部分,请查看官方文档
版本:2.2.5

参考

HttpRunner V2.x 中文使用文档

变量的申明和引用

承接上文,测试脚本天气.yml中,我们将city设置为变量,它是在variables被定义的,然后可以通过 $ + 变量名称 的方式引用变量,他是以$开头,特殊字符结尾,取中间的字符串。
在一些场景中,需要引用参数拼接字符串时,可以使用${变量名称}的方式引用。
同时,可以在extract中提取返回数据,作为变量。

# 测试名称(必须的),String
name: 获取 城市 的天气
# 变量(可选的), List,被上级(testcases,testsuite)覆盖
variables:
    # 设置变量,城市
    city: 上
    baseUrl: https://www.apiopen.top
    path: /weatherApi
    msg: "成功!"
# 默认域名(可选的).String
base_url: $baseUrl
# 请求参数(必须的), dict, 与request中的参数相同
request:
    method: GET
    url: $path
    params:
        # 通过 $+参数名称 的形式,应用变量
        city: ${city}海
# 提取器(可选的), dict,提取返回参数
extract:
    code: content.code
# 验证(可选的), list
validate:
    - eq: [$code , 200]
    - eq: [content.msg, $msg]
# 前置处理(可选的),list
setup_hooks:
# 后置处理(可选的),list
teardown_hooks:

函数定义和调用

定义

在项目目录下的debugtalk.py文件中新增函数。

import uuid

def uuk():
    """
    获取UUID
    :return: 
    """
    return str(uuid.uuid1())

引用

yaml文件中调用方法的形式是:${fun(var)},如:

variables:
    # 设置变量,城市
    city: 上海
    baseUrl: https://www.apiopen.top
    path: /weatherApi
    msg: "成功!"
    # 通过调用debugtalk.py 的 uuk() 方法随机获取 UUID
    uuk: ${uuk()}

httprunner内定义的方法:

  • ${parameterize(csv_file)}${P(csv_file)}: 加载csv文件并检查文件内容格式,其中,csv_file为csv文件路径
    elif function_name in ["parameterize", "P"]:
        from httprunner import loader
        return loader.load_csv_file
  • ${environ(variable_name)}${ENV(variable_name)}:获取环境变量的值。其中,variable_name为变量名称。环境变量可以通过.env文件定义
    elif function_name in ["environ", "ENV"]:
        return utils.get_os_environ
  • built-in中的函数
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
# encoding: utf-8

"""
Built-in dependent functions used in YAML/JSON testcases.
"""

import datetime
import json
import os
import random
import re
import string
import time

import filetype
from httprunner.compat import basestring, builtin_str, integer_types, str
from httprunner.exceptions import ParamsError
from requests_toolbelt import MultipartEncoder

PWD = os.getcwd()


###############################################################################
##  built-in functions
###############################################################################

def gen_random_string(str_len):
    """ generate random string with specified length
    """
    return ''.join(
        random.choice(string.ascii_letters + string.digits) for _ in range(str_len))

def get_timestamp(str_len=13):
    """ get timestamp string, length can only between 0 and 16
    """
    if isinstance(str_len, integer_types) and 0 < str_len < 17:
        return builtin_str(time.time()).replace(".", "")[:str_len]

    raise ParamsError("timestamp length can only between 0 and 16.")

def get_current_date(fmt="%Y-%m-%d"):
    """ get current date, default format is %Y-%m-%d
    """
    return datetime.datetime.now().strftime(fmt)


###############################################################################
##  upload files with requests-toolbelt
#   e.g.
#   - test:
#      name: upload file
#      variables:
#          file_path: "data/test.env"
#          multipart_encoder: ${multipart_encoder(file=$file_path)}
#      request:
#          url: /post
#          method: POST
#          headers:
#              Content-Type: ${multipart_content_type($multipart_encoder)}
#          data: $multipart_encoder
#      validate:
#          - eq: ["status_code", 200]
#          - startswith: ["content.files.file", "UserName=test"]
###############################################################################

def multipart_encoder(**kwargs):
    """ initialize MultipartEncoder with uploading fields.
    """
    def get_filetype(file_path):
        file_type = filetype.guess(file_path)
        if file_type:
            return file_type.mime
        else:
            return "text/html"

    fields_dict = {}
    for key, value in kwargs.items():

        if os.path.isabs(value):
            _file_path = value
            is_file = True
        else:
            global PWD
            _file_path = os.path.join(PWD, value)
            is_file = os.path.isfile(_file_path)

        if is_file:
            filename = os.path.basename(_file_path)
            with open(_file_path, 'rb') as f:
                mime_type = get_filetype(_file_path)
                fields_dict[key] = (filename, f.read(), mime_type)
        else:
            fields_dict[key] = value

    return MultipartEncoder(fields=fields_dict)


def multipart_content_type(multipart_encoder):
    """ prepare Content-Type for request headers
    """
    return multipart_encoder.content_type


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

""" built-in hooks
"""
def sleep_N_secs(n_secs):
    """ sleep n seconds
    """
    time.sleep(n_secs)

以及python的内置函数

getattr(builtins, function_name)

环境变量

默认情况下,在自动化测试项目的根目录中,创建.env文件,并将敏感数据信息放置到其中,存储采用 name=value 的格式

USERNAME=leolee
PASSWORD=123456

引用环境变量,可以通过在YAML/JSON 脚本中使用${environ(variable_name)}${ENV(variable_name)}获取环境变量的值,variable_name为变量名称

运行是切换环境

默认情况下,使用hrun api/天气.yml --log-level DEBUG运行测试时,会默认加载根目录中的 .env文件.

没有指定环境变量文件
新建一个.env文件dev.env,在文件中新增环境变量
新增环境变量文件
运行测试时,指定加载的环境变量文件--dot-env-path + 环境文件路径
hrun api/天气.yml --log-level DEBUG --dot-env-path dev.env
指定环境变量文件

相关文章

网友评论

      本文标题:httprunner学习实践(三)--变量和方法的使用

      本文链接:https://www.haomeiwen.com/subject/umfirctx.html