models.py

昨天体验的时候我们分别执行了httprunner -h,httprunner startproject demo, httprunner run demo,但是源码中其调用了其他文件中的方法所以暂时先不分析cli.py了,先从根本开始models.py

可用资料

typing[类型提示]: https://docs.python.org/zh-cn/3/library/typing.html

pydantic[类型校验]: https://pydantic-docs.helpmanual.io/

用上这两个库就有点强类型语言的味儿了

泛型: https://docs.python.org/zh-cn/3/library/typing.html#generics

枚举: https://docs.python.org/zh-cn/3/library/enum.html

导包分析

import os   # 系统包
from enum import Enum # 枚举类
from typing import Any # Any 表示 任意类型
from typing import Dict # dict 的泛型版本。
from typing import Text # Text 是 str 的别名
from typing import Union # 联合类型;Union[X, Y] 的意思是,非 X 即 Y
from typing import Callable # 可调类型; Callable[[int], str] 是把(int)转为 str 的函数。
from typing import List # list 的泛型版本。
from pydantic import BaseModel # pydantic定义对象的基类
from pydantic import Field # pydantic 中 字段扩展定义
from pydantic import HttpUrl # 校验url地址的

类型别名定义

该系列中个人对类型的看法/叫法如下

  1. Text => str / 文本
  2. List => list / 列表
  3. Dict => dict / 字典
Name = Text     # Name 的本质 其实就是 Text(Text 本质又是 str)
Url = Text
BaseUrl = Union[HttpUrl, Text] # 是url 或者 Text 两者之一
VariablesMapping = Dict[Text, Any] # key 是 Text ,value 是任意类型
FunctionsMapping = Dict[Text, Callable] # key 是 Text, value是可调用对象
Headers = Dict[Text, Text] # key 是 str, value 也是 str
Cookies = Dict[Text, Text] # 同上
Verify = bool # 布尔类型
Hooks = List[Union[Text, Dict[Text, Text]]] # 列表,列表中的元素是 str 或者 key,value 都是 str
Export = List[Text] # 列表,列表中元素是 str
Validators = List[Dict] # 列表,列表中元素是 字典
Env = Dict[Text, Any] # 字典 key 是 str, value 是任意类型

请求方法

# 枚举类,其中属性是 Text类型
class MethodEnum(Text, Enum):
GET = "GET"
POST = "POST"
PUT = "PUT"
DELETE = "DELETE"
HEAD = "HEAD"
OPTIONS = "OPTIONS"
PATCH = "PATCH"

其余模型

避免篇幅过长,这里直接复制源代码 附上注释

class TConfig(BaseModel):
"""测试配置模型"""
name: Name
verify: Verify = False
base_url: BaseUrl = ""
# Text: prepare variables in debugtalk.py, ${gen_variables()}
# 变量
variables: Union[VariablesMapping, Text] = {}
parameters: Union[VariablesMapping, Text] = {}
# setup_hooks: Hooks = []
# teardown_hooks: Hooks = []
export: Export = []
path: Text = None
weight: int = 1 class TRequest(BaseModel):
"""测试请求模型"""
"""requests.Request model""" method: MethodEnum # 这里的类型是前面定义的请求方法枚举
url: Url
# 查询参数
params: Dict[Text, Text] = {}
headers: Headers = {}
# alias 是别名, json 数据
req_json: Union[Dict, List, Text] = Field(None, alias="json")
# data 数据 - 表单
data: Union[Text, Dict[Text, Any]] = None
cookies: Cookies = {}
timeout: float = 120
# 允许重定向
allow_redirects: bool = True
# 安全验证
verify: Verify = False
upload: Dict = {} # used for upload files class TStep(BaseModel):
"""测试步骤模型"""
name: Name
# 步骤可以是一个请求模型
request: Union[TRequest, None] = None
# 用例
testcase: Union[Text, Callable, None] = None
# 变量
variables: VariablesMapping = {}
setup_hooks: Hooks = []
teardown_hooks: Hooks = []
# used to extract request's response field
# 提取响应字段
extract: VariablesMapping = {}
# used to export session variables from referenced testcase
# 导出字段
export: Export = []
# 验证器
validators: Validators = Field([], alias="validate")
# 验证脚本
validate_script: List[Text] = [] class TestCase(BaseModel):
"""测试用例模型 = 测试配置 + 测试步骤"""
config: TConfig
teststeps: List[TStep] class ProjectMeta(BaseModel):
"""项目配置模型"""
# debugtalk.py 文件内容
debugtalk_py: Text = "" # debugtalk.py file content
debugtalk_path: Text = "" # debugtalk.py file path
# .env 文件路径
dot_env_path: Text = "" # .env file path
# 在 debugtalk.py 中定义的函数
functions: FunctionsMapping = {} # functions defined in debugtalk.py
env: Env = {}
# 项目根目录
RootDir: Text = os.getcwd() # project root directory (ensure absolute), the path debugtalk.py located class TestsMapping(BaseModel):
"""测试集合"""
project_meta: ProjectMeta
testcases: List[TestCase] class TestCaseTime(BaseModel):
"""测试用例时间"""
start_at: float = 0
start_at_iso_format: Text = ""
duration: float = 0 class TestCaseInOut(BaseModel):
"""测试用例输入输出"""
# 输入参数
config_vars: VariablesMapping = {}
# 导出参数
export_vars: Dict = {} class RequestStat(BaseModel):
"""请求状态"""
content_size: float = 0
response_time_ms: float = 0
elapsed_ms: float = 0 class AddressData(BaseModel):
"""地址数据"""
client_ip: Text = "N/A"
client_port: int = 0
server_ip: Text = "N/A"
server_port: int = 0 class RequestData(BaseModel):
"""请求数据模型"""
method: MethodEnum = MethodEnum.GET
url: Url
headers: Headers = {}
cookies: Cookies = {}
body: Union[Text, bytes, List, Dict, None] = {} class ResponseData(BaseModel):
"""响应数据模型"""
status_code: int
headers: Dict
cookies: Cookies
encoding: Union[Text, None] = None
content_type: Text
body: Union[Text, bytes, List, Dict] class ReqRespData(BaseModel):
"""请求响应数据模型"""
request: RequestData
response: ResponseData class SessionData(BaseModel):
"""会话数据"""
"""request session data, including request, response, validators and stat data""" success: bool = False
# in most cases, req_resps only contains one request & response
# while when 30X redirect occurs, req_resps will contain multiple request & response
req_resps: List[ReqRespData] = []
stat: RequestStat = RequestStat()
address: AddressData = AddressData()
validators: Dict = {} class StepData(BaseModel):
"""步骤数据模型"""
"""teststep data, each step maybe corresponding to one request or one testcase""" success: bool = False
name: Text = "" # teststep name
data: Union[SessionData, List['StepData']] = None
export_vars: VariablesMapping = {} StepData.update_forward_refs() class TestCaseSummary(BaseModel):
"""测试用例结果"""
name: Text
success: bool
case_id: Text
time: TestCaseTime
in_out: TestCaseInOut = {}
log: Text = ""
step_datas: List[StepData] = [] class PlatformInfo(BaseModel):
httprunner_version: Text
python_version: Text
platform: Text class TestCaseRef(BaseModel):
name: Text
base_url: Text = ""
testcase: Text
variables: VariablesMapping = {} class TestSuite(BaseModel):
"""测试套件"""
config: TConfig
testcases: List[TestCaseRef] class Stat(BaseModel):
"""结果集状态"""
total: int = 0
success: int = 0
fail: int = 0 class TestSuiteSummary(BaseModel):
"""测试套件结果收集"""
success: bool = False
stat: Stat = Stat()
time: TestCaseTime = TestCaseTime()
platform: PlatformInfo
testcases: List[TestCaseSummary]

最后

上述内容个人理解,如有错误欢迎指出交流。

HttpRunner3源码阅读:2. 模型定义的更多相关文章

  1. HttpRunner3源码阅读: 1. 目录结构分析

    初衷 身处软件测试行业的各位应该都有耳闻HttpRunner 开源测试工具/框架(接口测试),作者博客 为什么出这系列? 不少测试同行都建议阅读HttpRunner,源码学习其设计思想. 社区当下Py ...

  2. linux源码阅读笔记 数组定义

    在阅读linux源码的过程中遇到了下面的略显奇怪的结构体数组定义. static struct hd_struct{ long start_sect; long nr_sects; }hd[10]={ ...

  3. HttpRunner3源码阅读:4. loader项目路径加载,用例文件转换、方法字典生成

    loader.py 这个文件中主要是对yaml,json用例加载转换成用例处理, 预置函数加载成方法字典,路径加载等 可用资料 [importlib]. https://docs.python.org ...

  4. HttpRunner3源码阅读:7.响应后处理 response.py

    response 上一篇说的client.py来发送请求,这里就来看另一个response.py,该文件主要是完成测试断言方法 可用资料 jmespath[json数据取值处理]: https://g ...

  5. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

  6. 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类

    21_BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类 BasicTaskScheduler基本任务调度器 BasicTaskScheduler基 ...

  7. 17 任务调度相关类综述——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  8. 【 js 基础 】【 源码学习 】backbone 源码阅读(一)

    最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-stud ...

  9. Pytorch版本yolov3源码阅读

    目录 Pytorch版本yolov3源码阅读 1. 阅读test.py 1.1 参数解读 1.2 data文件解析 1.3 cfg文件解析 1.4 根据cfg文件创建模块 1.5 YOLOLayer ...

随机推荐

  1. Serverless Web Function 实践教程(一):快速部署 Node.js Web 服务

    作为目前广受欢迎的 Web 服务开发语言,Node.js 提供了众多支持 HTTP 场景的相关功能,可以说是为 Web 构建而生.因此,基于 Node.js,也诞生了多种 Web 服务框架,它们对 N ...

  2. WEB 三维引擎在高精地图数据生产的探索和实践

    1. 前言 高精地图(High Definition Map)作为自动驾驶安全性不可或缺的一部分,能有效强化自动驾驶的感知能力和决策能力,提升自动驾驶的等级.对于自动驾驶来说,高精地图主要是给机器用的 ...

  3. 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...

  4. 《手把手教你》系列基础篇(五)-java+ selenium自动化测试- 创建首个自动化脚本(详细教程)

    1.简介 前面几篇宏哥介绍了两种(java和maven)环境搭建和三大浏览器的启动方法,这篇文章宏哥将要介绍第一个自动化测试脚本.前边环境都搭建成功了,浏览器也驱动成功了,那么我们不着急学习其他内容, ...

  5. 2021年Wordpress手把手教你做个独立站——部署篇

    2021年Woocommerce电商主题的安装部署教程 Woocommerce是一个Wordpress的一个流行的电商插件.完成Wordpress的安装即已完成80%.剩下的便是去寻找一款合适的自己喜 ...

  6. Vue style与css的var()

    vue绑定style直接给css的var变量传递一个值,然后结合css的var()函数使用这个值. 在data里面定义一个变量然后给定一个值,后期修改这个值之后,所有依赖这个变量的css样式都会被响应 ...

  7. 导入项目发现没得右边没得maven

    使用ctrl + shift+A点Add Maven Project 就行了 参考:https://www.cnblogs.com/Juff-code/p/13390356.html

  8. js实现页面下拉,区块(文字,图片等)左右淡入淡出效果

    html: <div class="box"> <span class="historybox"> </span> < ...

  9. 消息队列——kafka

    原文:再过半小时,你就能明白kafka的工作原理了 会出现什么情况呢? 1.为了这个女朋友,我请假回去拿(老板不批). 2.小哥一直在你楼下等(小哥还有其他的快递要送). 3.周末再送(显然等不及). ...

  10. mysql中的条件语句case when/if函数

    主要知识点为case函数,if函数,ifnull函数,elt函数几部分,主要用于mysql语句中的逻辑判断 待操作的表如下: p.p1 { margin: 0; font: 16px Menlo; c ...