您的位置:首页 > 理论基础 > 计算机网络

HttpRunner3源码阅读:9. 测试用例中的类定义testcase

2021-08-09 18:10 841 查看

testcase

testcase.py
这里主要写了一个测试文件里的几个组成类及其方法(Config/Step...)

可用资料

inspect[类型检查...]:https://docs.python.org/zh-cn/3/library/inspect.html property[方法转为只读属性]:https://docs.python.org/zh-cn/3/library/functions.html?highlight=property#property

导包

import inspect  # :类型检查、获取源代码、检查类与函数、检查解释器的调用堆栈。
from typing import Text, Any, Union, Callable

from httprunner.models import (
TConfig,
TStep,
TRequest,
MethodEnum,
TestCase,
)

源码附注释

Config类

class Config(object):
# 接收一个name参数
def __init__(self, name: Text):
# 以下定义的都是私有属性
# 该属性无法通过对象.属性名访问
# Config().__name
# 但可以通过对象._类名+属性名访问
# Config()._Config__name
# _属性名,则为一种规范表示不想被当前程序外的地方访问,但可以通过对象.属性名方法
self.__name = name
self.__variables = {}
self.__base_url = ""
self.__verify = False
self.__export = []
# 这个权重 是用在locust 中的
self.__weight = 1
# 返回调用方堆栈的帧记录列表。返回列表中的第一个条目表示调用方; 最后一个条目表示堆栈上的最外层调用。
caller_frame = inspect.stack()[1]
self.__path = caller_frame.filename

# 修饰的方法可用属性方式调用x.name
@property
def name(self) -> Text:
return self.__name

@property
def path(self) -> Text:
return self.__path

@property
def weight(self) -> int:
return self.__weight

# 设置配置信息以下...
def variables(self, **variables) -> "Config":
"""变量字典合并"""
self.__variables.update(variables)
return self

def base_url(self, base_url: Text) -> "Config":
self.__base_url = base_url
return self

def verify(self, verify: bool) -> "Config":
self.__verify = verify
return self

def export(self, *export_var_name: Text) -> "Config":
# 末尾一次性追加另一个序列中的多个值
self.__export.extend(export_var_name)
return self

def locust_weight(self, weight: int) -> "Config":
self.__weight = weight
return self

def perform(self) -> TConfig:
return TConfig(
name=self.__name,
base_url=self.__base_url,
verify=self.__verify,
variables=self.__variables,
export=list(set(self.__export)),
path=self.__path,
weight=self.__weight,
)

StepRequestValidation类

class StepRequestValidation(object):
# 传入一个测试步骤模型对象
def __init__(self, step_context: TStep):
self.__step_context = step_context

# 以下各验证方法
def assert_equal(
self, jmes_path: Text, expected_value: Any, message: Text = ""
) -> "StepRequestValidation":
""" jmes_pathn: json搜索表达式, expected_value:期望值
message: 描述
"""
# 追加到验证器列表
self.__step_context.validators.append(
{"equal": [jmes_path, expected_value, message]}
)
return self
# 不相等
def assert_not_equal(
self, jmes_path: Text, expected_value: Any, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"not_equal": [jmes_path, expected_value, message]}
)
return self

def assert_greater_than(
self, jmes_path: Text, expected_value: Union[int, float], message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"greater_than": [jmes_path, expected_value, message]}
)
return self

def assert_less_than(
self, jmes_path: Text, expected_value: Union[int, float], message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"less_than": [jmes_path, expected_value, message]}
)
return self

def assert_greater_or_equals(
self, jmes_path: Text, expected_value: Union[int, float], message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"greater_or_equals": [jmes_path, expected_value, message]}
)
return self

def assert_less_or_equals(
self, jmes_path: Text, expected_value: Union[int, float], message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"less_or_equals": [jmes_path, expected_value, message]}
)
return self

def assert_length_equal(
self, jmes_path: Text, expected_value: int, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"length_equal": [jmes_path, expected_value, message]}
)
return self

def assert_length_greater_than(
self, jmes_path: Text, expected_value: int, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"length_greater_than": [jmes_path, expected_value, message]}
)
return self

def assert_length_less_than(
self, jmes_path: Text, expected_value: int, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"length_less_than": [jmes_path, expected_value, message]}
)
return self

def assert_length_greater_or_equals(
self, jmes_path: Text, expected_value: int, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"length_greater_or_equals": [jmes_path, expected_value, message]}
)
return self

def assert_length_less_or_equals(
self, jmes_path: Text, expected_value: int, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"length_less_or_equals": [jmes_path, expected_value, message]}
)
return self

def assert_string_equals(
self, jmes_path: Text, expected_value: Any, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"string_equals": [jmes_path, expected_value, message]}
)
return self

def assert_startswith(
self, jmes_path: Text, expected_value: Text, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"startswith": [jmes_path, expected_value, message]}
)
return self

def assert_endswith(
self, jmes_path: Text, expected_value: Text, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"endswith": [jmes_path, expected_value, message]}
)
return self

def assert_regex_match(
self, jmes_path: Text, expected_value: Text, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"regex_match": [jmes_path, expected_value, message]}
)
return self

def assert_contains(
self, jmes_path: Text, expected_value: Any, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"contains": [jmes_path, expected_value, message]}
)
return self

def assert_contained_by(
self, jmes_path: Text, expected_value: Any, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"contained_by": [jmes_path, expected_value, message]}
)
return self

def assert_type_match(
self, jmes_path: Text, expected_value: Any, message: Text = ""
) -> "StepRequestValidation":
self.__step_context.validators.append(
{"type_match": [jmes_path, expected_value, message]}
)
return self

def perform(self) -> TStep:
return self.__step_context

StepRequestExtraction

# 步骤中提取参数类,
# 提供验证方法,返回验证类对象 StepRequestValidation
class StepRequestExtraction(object):
def __init__(self, step_context: TStep):
self.__step_context = step_context

def with_jmespath(self, jmes_path: Text, var_name: Text) -> "StepRequestExtraction":
self.__step_context.extract[var_name] = jmes_path
return self

# def with_regex(self):
#     # TODO: extract response html with regex
#     pass
#
# def with_jsonpath(self):
#     # TODO: extract response json with jsonpath
#     pass

def validate(self) -> StepRequestValidation:
return StepRequestValidation(self.__step_context)

def perform(self) -> TStep:
return self.__step_context

RequestWithOptionalArgs

# 步骤中:Request请求 ,请求header等配置
# 提取数据, 校验,teardown_hook
class RequestWithOptionalArgs(object):
def __init__(self, step_context: TStep):
self.__step_context = step_context

def with_params(self, **params) -> "RequestWithOptionalArgs":
self.__step_context.request.params.update(params)
return self

def with_headers(self, **headers) -> "RequestWithOptionalArgs":
self.__step_context.request.headers.update(headers)
return self

def with_cookies(self, **cookies) -> "RequestWithOptionalArgs":
self.__step_context.request.cookies.update(cookies)
return self

def with_data(self, data) -> "RequestWithOptionalArgs":
self.__step_context.request.data = data
return self

def with_json(self, req_json) -> "RequestWithOptionalArgs":
self.__step_context.request.req_json = req_json
return self

def set_timeout(self, timeout: float) -> "RequestWithOptionalArgs":
self.__step_context.request.timeout = timeout
return self

def set_verify(self, verify: bool) -> "RequestWithOptionalArgs":
self.__step_context.request.verify = verify
return self

def set_allow_redirects(self, allow_redirects: bool) -> "RequestWithOptionalArgs":
self.__step_context.request.allow_redirects = allow_redirects
return self

def upload(self, **file_info) -> "RequestWithOptionalArgs":
self.__step_context.request.upload.update(file_info)
return self

def teardown_hook(
self, hook: Text, assign_var_name: Text = None
) -> "RequestWithOptionalArgs":
if assign_var_name:
self.__step_context.teardown_hooks.append({assign_var_name: hook})
else:
self.__step_context.teardown_hooks.append(hook)

return self

def extract(self) -> StepRequestExtraction:
return StepRequestExtraction(self.__step_context)

def validate(self) -> StepRequestValidation:
return StepRequestValidation(self.__step_context)

def perform(self) -> TStep:
return self.__step_context

RunRequest

# 请求前置:参数变量,setup_hook,请求最终调用RequestWithOptionalArgs
# 此方法Demo中有使用
class RunRequest(object):
def __init__(self, name: Text):
self.__step_context = TStep(name=name)

def with_variables(self, **variables) -> "RunRequest":
self.__step_context.variables.update(variables)
return self

def setup_hook(self, hook: Text, assign_var_name: Text = None) -> "RunRequest":
if assign_var_name:
self.__step_context.setup_hooks.append({assign_var_name: hook})
else:
self.__step_context.setup_hooks.append(hook)

return self

def get(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.GET, url=url)
return RequestWithOptionalArgs(self.__step_context)

def post(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.POST, url=url)
return RequestWithOptionalArgs(self.__step_context)

def put(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.PUT, url=url)
return RequestWithOptionalArgs(self.__step_context)

def head(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.HEAD, url=url)
return RequestWithOptionalArgs(self.__step_context)

def delete(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.DELETE, url=url)
return RequestWithOptionalArgs(self.__step_context)

def options(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.OPTIONS, url=url)
return RequestWithOptionalArgs(self.__step_context)

def patch(self, url: Text) -> RequestWithOptionalArgs:
self.__step_context.request = TRequest(method=MethodEnum.PATCH, url=url)
return RequestWithOptionalArgs(self.__step_context)

StepRefCase

# 需要传入步骤, Demo中并未使用该类,
class StepRefCase(object):
def __init__(self, step_context: TStep):
self.__step_context = step_context
# 结束时运行函数
def teardown_hook(self, hook: Text, assign_var_name: Text = None) -> "StepRefCase":
if assign_var_name:
self.__step_context.teardown_hooks.append({assign_var_name: hook})
else:
self.__step_context.teardown_hooks.append(hook)

return self
# 导出变量
def export(self, *var_name: Text) -> "StepRefCase":
self.__step_context.export.extend(var_name)
return self

def perform(self) -> TStep:
return self.__step_context

RunTestCase

# 步骤 -> 测试用例类(引入), 此方法Demo有案例
class RunTestCase(object):
def __init__(self, name: Text):
self.__step_context = TStep(name=name)

def with_variables(self, **variables) -> "RunTestCase":
self.__step_context.variables.update(variables)
return self

def setup_hook(self, hook: Text, assign_var_name: Text = None) -> "RunTestCase":
if assign_var_name:
self.__step_context.setup_hooks.append({assign_var_name: hook})
else:
self.__step_context.setup_hooks.append(hook)

return self
# testcase 测试用例类
def call(self, testcase: Callable) -> StepRefCase:
self.__step_context.testcase = testcase
return StepRefCase(self.__step_context)

def perform(self) -> TStep:
return self.__step_context

Step

# 步骤
class Step(object):
# 可以是以下5种对象
def __init__(
self,
step_context: Union[
StepRequestValidation,
StepRequestExtraction,
RequestWithOptionalArgs,
RunTestCase,
StepRefCase,
],
):
self.__step_context = step_context.perform()

@property
def request(self) -> TRequest:
return self.__step_context.request

@property
def testcase(self) -> TestCase:
return self.__step_context.testcase

def perform(self) -> TStep:
return self.__step_context
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: