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
相关文章推荐
- HttpRunner3源码阅读:4. loader项目路径加载,用例文件转换、方法字典生成
- HttpRunner3源码阅读:10.测试执行的处理 runner
- HttpRunner3源码阅读:3.工具文件
- Httprunner项目文件和测试用例组织
- httprunner(4)录制生成测试用例
- httprunner(5)编写测试用例
- httpRunner源码解读(1)
- HttpServletBean 源码阅读
- 根据测试用例的java源码自动生成TestNG的XML文件
- 自动化测试===Httprunner测试框架介绍
- 软件测试开发实战|接口自动化测试框架开发(pytest+allure+aiohttp+用例自动生成)
- socket客户端用例测试-HTTP
- httprunner(8)用例调用-RunTestCase
- 测试用例(TestCase)
- 2019-03-18HttpRunnerManager用例配置-03:自定义辅助函数生成随机数(debugtalk.py )
- 根据测试用例的java源码自动生成TestNG的XML文件
- httpclient http连接池 源码阅读
- gtest 学习之五 测试用例中定义类
- 第十周项目一 阅读下面的定义,请说出在测试函数中不同情况的调用产生的结果(5 d)
- unittest--testcase的文件名不遵循规则时,testrunner不能正常加载测试用例