tep0.6.0 更新聊聊 pytest 变量接口用例 3 个级别复用
tep 是一款测试工具,在 pytest 测试框架基础上集成了第三方包,提供项目脚手架,帮助以写 Python 代码方式,快速实现自动化项目落地。fixture 是 pytest 核心技术,本文聊聊如何使用 fixture 完成变量、接口、用例 3 个级别复用。
tep 是一款测试工具,在 pytest 测试框架基础上集成了第三方包,提供项目脚手架,帮助以写 Python 代码方式,快速实现自动化项目落地。fixture 是 pytest 核心技术,本文聊聊如何使用 fixture 完成变量、接口、用例 3 个级别复用。
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 本文开发内容 用例管理是对用例进行增删改查,按照前面文章的思路,把它做出来应该不难,如果你已经自己写好了,那么可以和本文提交的代码比较下看看。除了增删改查,用例管理还需要提供运行用例的入口,在操作列添加一个运行按钮,单条用例运行,并弹窗展示运行结果。用例列表需要能看到每条用例执行情况,添加表格列用于展示,其中“运行结果”列要有超链接,点击查看上次运行结果。为了避免修改别人用例出错,还需要有个复制用例功能。除了在线编辑,平台应支持下载项目环境到本地,无缝切换到 PyCharm,让新用户快速上手。综上所述,本文开发内容如下: 用例增删改查。 运行按钮,点击后弹出“运行用例结果”。 添加表格展示列,其中“运行结果”用颜色区分不同结果状态:passed,failed,error,点击超链接后弹出“查看用例结果”。 复制按钮,点击后生成一条复制的新用例。 新增/编辑页面,添加运行按钮。 运行/查看页面,添加编辑按钮。 下载环境到本地。 工作量主要在前端,后端先做一部分。 编写后端代码 编辑 teprunner/urls.py,添加路由: 除了增删改查,还添加了 2 个接口,一个用于获取用例运行的结果,一个用于复制测试用例。 编辑 teprunner/models.py,添加模型: 第一个 Model 是 Case,没有定义 name 字段,实际上用例 ID 和用例描述已经够用了,name 不知道填什么,有点多余。第二个 Model 是 CaseResult,会记录运行结果,这个运行结果是从 pytest 执行日志最后一行的 Summary 截取出来的,比如 1 passed,1 failed,耗时也是从 Summary 截取出来的。output 存放代码运行后打到控制台的输出日志。最后三个字段记录运行环境、运行人和运行时间,运行时间取的数据库记录被添加/更新的时间。添加好以后迁移到数据库中: python manage.py makemigrations python manage.py migrate 编辑 teprunner/serializers.py,添加序列化器,第一个序列化器是 CaseSerializer: 只关联了 Case 模型的字段。 第二个序列化器是 CaseListSerializer: 它主要用来返回用例列表的数据,除了用例本身,还需要用例结果。serializers.SerializerMethodField 用于自定义序列化字段,定义好字段后,在下面添加get_前缀+字段名的方法,这是 Django 的规则,然后在方法内部添加取值代码,比如 get_result(),instance 是指 Meta.model 定义的模型,这里就等同于 Case,通过 instance.id 获取到 Case.id 并赋值给 case_id 变量,从 CaseResult 的对象中过滤 case_id 匹配的用例结果,按运行时间倒序,取最新 1 条结果的 result 字段的值。其他字段的处理是类似的,runTime 这里做了下日期格式化: ...
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 本文开发内容 现在正式进入测试相关功能开发。teprunner 测试平台底层是 pytest,中间层是 tep,还没了解的朋友可以先看看 tep 的文章,整个平台的设计思路和后面用例的执行都会基于这个工具。tep 的测试用例是放在.py 文件里面的,全局变量或者说环境变量是引用的 env_vars,公共函数和复用接口是引用的 fixtures,在做成平台后,需要把这两个部分独立为两个功能模块。多个项目的接口自动化数据需要隔离开来,要有个项目管理功能。本文将开发四个用例前置模块: 后台管理–项目管理 接口自动化–语法说明 接口自动化–环境变量 接口自动化–fixtures 语法说明给出了环境变量、fixtures、用例示例(单个接口、多个接口–增删改查)、请求方法(get、post、put、delete)的使用方法。 编写后端代码 先创建名为 teprunner 的 app: django-admin startapp teprunner 在 settings 的 INSTALLED_APPS 中添加配置让 app 生效: 并在 urls.py 添加路由: 编辑 user/fixtures/user.json,添加一个接口自动化的菜单: 截图只截了管理员,测试和开发角色,也需要添加上。access 均为 true,这三个角色都可以访问。添加后把数据同步到数据库: python manage.py loaddata user 编辑 teprunner/models.py,新增模型: 包括了项目、环境变量和 fixture 三张表。Project.env_config 用于给项目配置多个环境。不同项目不同环境的环境变量不一样,在 EnvVar 中添加了 project_id 和 env_name,并按(“project_id”, “env_name”, “name”)作为唯一键,不允许重复。不同项目的 fixtures 不同,不关心环境,在 Fixture 中只添加了 project_id。 Fixture.code 用于存放代码,字段类型为 models.TextField,容纳更多字符。 models 编写好后,迁移到数据库: ...
tep 的设计理念是让人人都可以用 Python 写自动化,本文就来介绍如何用 tep 完成增删改查接口自动化。
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 系统架构 前端、后端、pytest 均以Docker容器运行服务,单独的容器化执行引擎,项目环境隔离,即用即取,用完即弃,简单,高效。 前端容器:页面交互,请求后端,展示 HTML 报告 后端容器:接收前端请求,启动任务,构建镜像,触发运行 pytest,挂载 HTML 报告 pytest 容器:拉取项目代码,指定目录执行,生成 HTML 报告 说明:构建镜像目前是在宿主机启动后端服务来执行 docker 命令的,暂未支持 Kubernetes 编排。宿主机安装了 Docker,启动服务后,可以执行 docker 命令。如果采用容器部署后端,容器里面不包含 Docker,无法构建,个人想法是可以借助 K8S 来编排,当前版本还未实现 系统流程 支持 2 种运行模式配置:容器和本地。 容器模式:判断是否支持 docker,如果支持,构建 pytest 镜像,在构建时,通过 git 拉取项目代码,再运行容器,按照指定目录执行 pytest,生成测试报告,并将报告文件挂载到后端。如果不支持,降级为本地运行。 本地模式:模拟容器行为,在本地目录拉取代码,执行 pytest,生成测试报告。 效果展示 任务管理: 容器模式: 本地模式: 平台大改造 pytestx 平台更轻、更薄,移除了用例管理、任务关联用例相关功能代码,只保留真正的任务调度功能,backend 的 requirements.txt 解耦,只保留后端依赖,pytest 相关依赖转移到 tep-project。 那如何管理用例呢?约定大于配置,我们约定 pytest 项目已经通过目录维护好了一个稳定的自动化用例集,也就是说需要通过平台任务调度的用例,都统一存放在目录 X 下,这些用例基本不需要维护,可以每日稳定执行,然后将目录 X 配置到平台任务信息中,按指定目录执行用例集。对于那些不够稳定的用例,就不能放到目录 X 下,需要调试好以后再纳入。 为什么不用 marker?pytest 的 marker 确实可以给测试用例打标记,也有人是手动建立任务和用例进行映射,这些方式都不如维护一个稳定的自动化用例集方便,在我们公司平台上,也是维护用例集,作为基础用例集。使用 pytest 项目同理。 ...
本文是一篇过渡,在进行用例管理模块开发之前,有必要把入门篇开发完成的代码部署到 Linux 系统 Docker 中,把部署流程走一遍,这个过程对后端设计有决定性影响。
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 背景 在 2022 年 7 月 6 日我曾组织过一次开源测试平台开发报名,有 50+人报名,到 2023 年 1 月 28 日项目暂停,如大家在 Gittee 看到的,除我以外,只有 1 个人真正提交了代码:奉孝。 原因如其中一位同学所说:“感觉我们大部份还是缺少从 0 到 1 的经验,负责的内容有时候不要知道从哪下手,又少了点积极性”。描述得很贴切,可能刚开始动力很足,但因为缺少经验,不够积极,最后实践不了。说的很好,就是做不到。也很无奈。 二次启动,分为 2 个阶段,第一个阶段是学习阶段,我带着大家一起把 teprunner 平台从 0 到 1 开发一遍,把需要掌握的知识先学一遍,保证有一定基础,挑战能够独立完成模块开发。第二个阶段是开发阶段,共同完成 EasyPytest 测试平台开发,学以致用,加深对前后端分离项目开发的理解,具有真实的平台开发实践。 学习阶段 你都不维护了,我为什么还要学 teprunner?Django 没意思?我想学 FastAPI? teprunner 有一套完整教程,包括前后端源码、11 篇电子书教程、2 小时视频讲解,虽然我因为工作原因没有继续维护 teprunner,但是它仍然非常适合初学者入门学习测试开发,掌握里面的知识,对于后续学习其他技术,都有很大帮助。我的技术提升除了二刷《流畅的 Python》和编写了 tep 开源工具,最大的提升就是完成了 teprunner 测试平台开发,如果你也能自己动手完成一遍,一定有极大提升。 Django、Flask、FastAPI、SpringBoot,我认为从入门者角度来说,Django 是最适合的,它属于开箱即用的框架,很多东西都给你准备好了,你用就行,避免刚开始就陷入环境搭建,三方库拼装、数据库维护的麻烦中,降低理解门槛和操作难度。学会了 Django,再学其他的,也很简单,一通百通。刚开始学习,学哪个不是最重要的,最重要的是先学会一个,迈出第一步。以我的经验来说,学习成熟框架 Django 是个正确选择。 开发阶段 EasyPytest 的后端把 Django 切换为了 FastAPI,掌握了 Django,再对比 FastAPI,就能对后端开发框架有更深入的理解。就像我学 Python 和 Java 一样,只学一门百思不得其解,对比一看,豁然开朗。目前已经完成了登录、首页、用户管理的开发,Gitee 也有相应源码。未来的规划,是做 teprunner 的升级版,实现 pytest 平台化,80%工作本地开发脚本,20%工作交给平台编排运行。 ...
温馨提示:开发指南,根据 V2.0.0 编写,不随版本更新维护,仅供入门参考。最新实现请结合教程和源码阅读,教程会在版本发布后维护。
如果没有这次全量数据对比工具,那么也许这个历史问题会继续隐藏着,直到发生线上事故才暴露出来,毕竟人工抽样验证发现的概率只有5.8%。
本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 概览 脚手架: 目录: 用例代码: """ 测试登录到下单流程,需要先启动后端服务 """ test_data = { "查询SKU": { "skuName": "电子书" }, "添加购物车": { "skuId": 123, "skuNum": 2 }, "下单": { "orderId": 222, "payAmount": "0.2" }, "支付": { "skuId": 123, "price": 0.1, "skuNum": 2, "totalPrice": 0.2 }, } case_vars = dict() def test(http, login_headers, file_data): # 搜索商品 url = file_data["domain"] + "/api/tasks/mock/searchSku" body = test_data["查询SKU"] response = http("get", url=url, headers=login_headers, params=body) assert response.status_code < 400 case_vars["skuId"] = response.jsonpath("$.skuId") case_vars["skuPrice"] = response.jsonpath("$.price") # 添加购物车 url = file_data["domain"] + "/api/tasks/mock/addCart" body = test_data["添加购物车"] body["skuId"] = case_vars["skuId"] response = http("post", url=url, headers=login_headers, json=body) assert response.status_code < 400 case_vars["skuNum"] = response.jsonpath("$.skuNum") case_vars["totalPrice"] = response.jsonpath("$.totalPrice") # 下单 url = file_data["domain"] + "/api/tasks/mock/order" body = test_data["下单"] body["skuId"] = case_vars["skuId"] body["price"] = case_vars["skuPrice"] body["skuNum"] = case_vars["skuNum"] body["totalPrice"] = case_vars["totalPrice"] response = http("post", url=url, headers=login_headers, json=body) assert response.status_code < 400 case_vars["orderId"] = response.jsonpath("$.orderId") # 支付 url = file_data["domain"] + "/api/tasks/mock/pay" body = test_data["支付"] body["orderId"] = case_vars["orderId"] response = http("post", url=url, headers=login_headers, json=body) assert response.status_code < 400 assert response.jsonpath("$.success") == "true" 页面下载脚手架 启动平台前后端服务后,从页面下载脚手架,平台会拉取开源项目 tep-project 最新代码,打成压缩包,生成下载文件,弹窗下载。 ...