Python 处理接口数据,这个函数太香了

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Python 处理接口数据 接口数据通常是 JSON 格式,Python 处理起来并不轻松。 方法一,json 文件。额外编写代码读取文件,接口参数很多,文件变多,难维护。 方法二,字典。JSON 可以直接粘贴到代码中,Python 认作字典,但语法有差异,JSON 的语法是 true/false/null,Python 的语法是 True/False/None,不兼容。 这两种方法都有共同的缺点,需要编写表达式来定位某个节点。 比如:body["a"][0]["x"]["m"] 字符串与占位符 占位符是一种很常见的文本替换技术,在任何编程语言中都有广泛应用。 Python 语法有个很特别的字符串,三引号字符串: test_json = """ { "bool": true, "x": null, "customerId": "123456", "items": [ { "productId": "987654", "quantity": 2, "price": 199.99 } ], "shippingAddress": { "recipientName": "张三", "streetAddress": "北京市朝阳区某街道123号", "city": "北京", "state": "北京", "postalCode": "100000", "country": "中国" }, "paymentMethod": { "type": "CreditCard", "cardNumber": "4111111111111111", "expiryDate": "12/25", "cvv": "123" }, "orderNotes": "请尽快发货,谢谢!" } """ 基本思路是,把 JSON 写在三引号字符串中,这能保留原生 JSON 格式,就像很多测试平台的做法一样,然后再通过占位符,直接替换其中的节点值。占位符不用编写表达式定位节点,在 JSON 字符串标记即可。 ...

年度大版本,tep3 回归纯粹 Python 接口测试框架

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 回顾 tep 是基于 pytest 开发的接口测试框架,上个版本从小工具升级为了关键字驱动框架,通过 pystats 发现最近半年仍然有 4000+人次在安装使用 tep。时隔 1 年后,我对 tep 进行了一次大版本改造,抛弃 tep2 的 Java 代码风格,重新回归到 tep1 的纯粹 Python 风格。 纯粹 Python 所谓纯粹 Python,体现在两个方面,一个方面是 tep 源码进行了重写,更加 Pythonic,自动化用例写起来也更加简单易懂;另一方面是抛弃了依赖 Java 的 Allure 和依赖 C++的 loguru,分别使用 Python 技术栈的 pytest-html 和 logging 替代。 tep3 版本 简介 tep 是 Try Easy Pytest 的首字母缩写,帮你轻松上手 pytest。 框架特点: 基于 pytest 封装,成熟、稳定且扩展性强。 框架完全由 Python 构建,没有混杂其他语言。 原生 Python 语法,学习 Python,零成本使用框架。 HAR 包转换 pytest 用例。 安装 支持 Python3.8 以上版本 ...

tep1.0.0 教程

正式版教程: https://dongfanger.gitee.io/blog/tep.html

当 Pytest 遇上 MVC 分层设计自动化用例就该这么写

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 引子 数据写在代码里,追求快速编写用例,是我设计 tep 的一个特点,这在个人编写时是一种非常良好的体验。但相比于 HttpRunner、JMeter 等来说,总觉得还差点意思。思考良久,总结为三个字:工程化。工程化是我近一年在学习 Java 并参与了 2 个测试平台模块开发,和写了几个小工具后,感受到的一种编程思想。而其中最明显的就是 Spring 的 MVC 分层设计。为了让 tep 更工程化,后续版本将以 MVC 模块编写用例为准,同时会兼容之前的脚本式快速编写。 示例 目录结构 测试用例都放在一个文件夹下: test_case:用例主程序; steps:测试步骤; data:纯粹的 json; 测试用例 test_case.py是测试用例,包含的只有测试步骤: import allure from examples.tests.LoginToPayFlow.steps.step_add_cart import step_add_cart from examples.tests.LoginToPayFlow.steps.step_order import step_order from examples.tests.LoginToPayFlow.steps.step_pay import step_pay from examples.tests.LoginToPayFlow.steps.step_search_sku import step_search_sku from utils.cache import TepCache from utils.step import Step """ 测试登录到下单流程,需要先运行utils/fastapi_mock.py """ @allure.title("从登录到下单支付") def test(login, env_vars, case_vars): case_vars.put("token", login["token"]) cache = TepCache(env_vars=env_vars, case_vars=case_vars) Step("搜索商品", step_search_sku, cache) Step("添加购物车", step_add_cart, cache) Step("下单", step_order, cache) Step("支付", step_pay, cache) TepCache 是“缓存”,包括 global_vars、env_vars、case_vars 三个级别的变量池。 ...

tep 支持 pytest-xdist 分布式执行用例及合并 Allure 报告

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 tep 近期更新频率较快,一方面是作者在积极投入到 tep 工具开发中;另一方面是我们聚集了 20 位小伙伴,一起合力打造EasyPytest 测试平台,teprunner 的 FastAPI 升级版本,依托于 tep,帮你高效管理 pytest 测试用例。陆续也会有平台开发日志发布,欢迎持续关注。 tep0.11.1 版本升级内容: 1、pytest-xdist 分布式执行用例,合并 Allure 报告; 2、global_vars 全局变量配置; 分布式执行用例 借助于 pytest-xdist,在命令行执行时添加参数-n auto: pytest -n auto pytest-xdist 会自动根据本地机器硬件配置,设置最优并发,并分发用例,分布式执行。 测试时先运行 main.py,然后在 case100 目录下执行pytest -n auto --tep-reports: 第一次串行,第二次 xdist 并行: 执行时间从 50s 一下降到 5s,性能提升还是非常的明显。 合并 Allure 报告 pytest-xdist 分布式执行,只要把 allure 源文件,也就是那一堆 json 文件,存到同一个目录下,报告的数据就是一体的,不需要单独合并。但是有个问题,tep 封装了--tep-reports 命令行参数一键生成 Allure 报告,背后的逻辑是在 pytest_sessionfinish hook 函数里面实现的,分布式执行时,每个 xdist 的 node 都是一个单独的 session,多个 node 就会生成多份报告: c ...

tep 时隔 8 个月迎来重大全新升级

tep 此次更新,旨在从“工具”升级为“框架”,为此做了大量的代码整洁工作,重新设计了部分功能,项目脚手架也焕然一新。

接口自动化项目落地之 HTTPBin 网站

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 接口自动化项目落地系列 找个开源网站或开源项目,用tep实现整套pytest接口自动化项目落地,归档到电子书,作为tep 完整教程的项目篇一部分。自从 tep 完整教程发布以后,tep 被越来越多小伙伴了解。教程只是纯理论,是骡子是马,拉出来遛遛才知道。做接口自动化项目落地,一方面是为了让自己脑海中的构想实实在在的呈现出来,现实和理想存在多少差距,不断尝试去弥补和修缮;另一方面也是方便读者朋友们学习使用,借助实际项目来练习,才能在赛道中弯道超车。 HTTPBin 网站 httpbin.org 是一个简单的在线提供 HTTP 服务的网站: 它能够用来对 HTTP 进行在线测试。 测试报告 HTTPBin 网站的接口自动化项目包含11 个用例集: 67 条测试用例: 自动化执行正确率 98.5%,其中有 1 条错误结果,是我故意为之的,因为想展示下断言失败的效果。 环境配置 包含 http 和 https 两套环境,因为 HTTPBin 支持 HTTP&HTTPS: fixtures/fixture_env_vars.py #!/usr/bin/python ## encoding=utf-8 from tep.fixture import * @pytest.fixture(scope="session") def env_vars(config): class Clazz(TepVars): env = config["env"] """变量定义开始""" # 环境变量 mapping = { "http": { # http环境 "domain": "http://httpbin.org", }, "https": { # https环境 "domain": "https://httpbin.org", } # 继续添加 } # 定义类属性,敲代码时会自动补全 domain = mapping[env]["domain"] """变量定义结束""" return Clazz() 配置默认为 http 环境: ...

民间流转的 pytest 项目结构设计

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 创建上图的 pytest 项目结构,只需要一条命令即可: tep startproject demo 前提是安装 tep0.9.8 版本: pip install tep==0.9.8 示例代码单独放在了 samples 文件夹下,可以放心将整个目录删除。其中的 db 演示了连接 MySQL 数据库,http 演示了 requests 常见用法和 tep request 的猴子补丁,login_pay 演示了从登陆到下单该如何编写脚本,包括 httprunner、mvc(不推荐)、tep(强烈推荐)三种写法。 fixtures 从 conftest.py 文件中单独拎了出来。这个设计与 Django 不谋而合,Django 也有个叫做 fixtures 的文件夹,用来存放测试数据。其实 pytest 的 fixture 的本意是可以用来做 setup 和 teardown 的,从这个意义来说,fixtures 就是存放测试数据的,比如封装登录接口为用例提供 token。 utils 存放了一些工具。比如自带的 fastapi 项目,request 猴子补丁,mitmproxy 抓包自动生成用例。request 猴子补丁可以自定义日志输出格式,在发送请求前后完成任何你想做的操作。 tep0.9.8 版本正式发布,对项目脚手架进行了精简,是为接下来的**《tep 完整教程帮你突破 pytest》**做好准备。

tep 集成 mitmproxy 录制流量自动生成用例

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 使用 操作过程非常简单,流程如下: ①配置过滤域名 必须配置,不然会有很多无效流量造成数据冗余。 ②启动代理 「示例」使用了反向代理,tep 自带 FastApi 启动 Mock 服务: 「实际」使用正向代理,并手动配置代理。命令说明在utils/mitm.py文件中有: ③录制流量 「示例」通过 Postman 发起请求: 「实际」在网页上点点点。 自动生成用例 用例就在tests/mitm实时生成好了,用例文件名为当前时间: 每录制一个请求,就能在测试用例中看到实时添加了一条测试步骤: # 接口描述 # 数据 # 请求 response = request( "{method}", url="{url}", headers={headers}, {body_grammar} ) # 数据提取 # var = response.jmespath("expression") # 断言 assert response.status_code < 400 录制完成以后,就可以再次编辑测试用例完善它。 原理 utils/mitm.py源码如下: #!/usr/bin/python ## encoding=utf-8 ## mitmproxy录制流量自动生成用例 import os import time from mitmproxy import ctx project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) tests_dir = os.path.join(project_dir, "tests") ## tests/mitm mitm_dir = os.path.join(tests_dir, "mitm") if not os.path.exists(mitm_dir): os.mkdir(mitm_dir) ## 当前时间作为文件名 filename = time.strftime("%Y%m%d_%H_%M_%S", time.localtime()) + ".py" case_file = os.path.join(mitm_dir, filename) ## 生成用例文件 template = """from tep.client import request def test(): """ if not os.path.exists(case_file): with open(case_file, "w", encoding="utf8") as fw: fw.write(template) class Record: def __init__(self, domains): self.domains = domains def response(self, flow): if self.match(flow.request.url): # method method = flow.request.method.lower() ctx.log.error(method) # url url = flow.request.url ctx.log.error(url) # headers headers = dict(flow.request.headers) ctx.log.error(headers) # body body = flow.request.text or {} ctx.log.error(body) with open(case_file, "a", encoding="utf8") as fa: fa.write(self.step(method, url, headers, body)) def match(self, url): if not self.domains: ctx.log.error("必须配置过滤域名") exit(-1) for domain in self.domains: if domain in url: return True return False def step(self, method, url, headers, body): if method == "get": body_grammar = f"params={body}" else: body_grammar = f"json={body}" return f""" # 接口描述 # 数据 # 请求 response = request( "{method}", url="{url}", headers={headers}, {body_grammar} ) # 数据提取 # var = response.jmespath("expression") # 断言 assert response.status_code < 400 """ ## ==================================配置开始================================== addons = [ Record( # 过滤域名 [ "http://www.httpbin.org", "http://127.0.0.1:5000" ], ) ] ## ==================================配置结束================================== """ ==================================命令说明开始================================== ## 正向代理 mitmdump -s mitm.py ## 反向代理 mitmdump -s mitm.py --mode reverse:http://127.0.0.1:5000 --listen-host 127.0.0.1 --listen-port 8000 ==================================命令说明结束================================== """ 通过 mitmproxy 命令启动代理后,获取当前时间作为文件名在tests/mitm下生成用例文件,给 addons 添加插件 Record 类,通过 response 钩子捕获请求信息,对请求进行域名过滤,域名匹配成功的请求就使用测试步骤代码模板,填充 method、url、headers、body 数据,追加到测试用例文件中。 ...

teprunner 测试平台入门级部署手册发布啦

很多朋友是因为 teprunner,也就是这个小众的 pytest 内核测试平台关注的公众号。为了让大家更好的上手 teprunner,我更新了它的 README,希望能让小伙伴们根据这些文档内容,一步一步的在自己本地电脑上把项目跑起来。项目跑起来之后,就可以参考前面一系列的学习教程,自己动手做一遍,在做的过程中和 teprunner 进行对比,不懂的点逐一突破,由点到面,完整实现。**这种学习方式能更快速的掌