diff --git a/Cache/work_login_init b/Cache/work_login_init new file mode 100644 index 0000000..da21250 --- /dev/null +++ b/Cache/work_login_init @@ -0,0 +1 @@ +75326e83b55ea4a745898a117ce7ef34b5e1 \ No newline at end of file diff --git a/report/__init__.py b/Enums/__init__.py similarity index 70% rename from report/__init__.py rename to Enums/__init__.py index 7c59819..52fa82a 100644 --- a/report/__init__.py +++ b/Enums/__init__.py @@ -1,4 +1,5 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/18 23:05 +# @Time : 2022/3/29 17:31 # @Author : 余少琪 + diff --git a/Enums/__pycache__/__init__.cpython-39.pyc b/Enums/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..a16c78d Binary files /dev/null and b/Enums/__pycache__/__init__.cpython-39.pyc differ diff --git a/Enums/__pycache__/allureAttchementType_enum.cpython-39.pyc b/Enums/__pycache__/allureAttchementType_enum.cpython-39.pyc new file mode 100644 index 0000000..8c9d0e0 Binary files /dev/null and b/Enums/__pycache__/allureAttchementType_enum.cpython-39.pyc differ diff --git a/Enums/__pycache__/assertType_enum.cpython-39.pyc b/Enums/__pycache__/assertType_enum.cpython-39.pyc new file mode 100644 index 0000000..b6547cc Binary files /dev/null and b/Enums/__pycache__/assertType_enum.cpython-39.pyc differ diff --git a/Enums/__pycache__/dependentType_enum.cpython-39.pyc b/Enums/__pycache__/dependentType_enum.cpython-39.pyc new file mode 100644 index 0000000..29f3c40 Binary files /dev/null and b/Enums/__pycache__/dependentType_enum.cpython-39.pyc differ diff --git a/Enums/__pycache__/notificationType_enum.cpython-39.pyc b/Enums/__pycache__/notificationType_enum.cpython-39.pyc new file mode 100644 index 0000000..ca1659f Binary files /dev/null and b/Enums/__pycache__/notificationType_enum.cpython-39.pyc differ diff --git a/Enums/__pycache__/requestType_enum.cpython-39.pyc b/Enums/__pycache__/requestType_enum.cpython-39.pyc new file mode 100644 index 0000000..ec76fb0 Binary files /dev/null and b/Enums/__pycache__/requestType_enum.cpython-39.pyc differ diff --git a/Enums/__pycache__/yamlData_enum.cpython-39.pyc b/Enums/__pycache__/yamlData_enum.cpython-39.pyc new file mode 100644 index 0000000..ec07354 Binary files /dev/null and b/Enums/__pycache__/yamlData_enum.cpython-39.pyc differ diff --git a/Enums/allureAttchementType_enum.py b/Enums/allureAttchementType_enum.py new file mode 100644 index 0000000..b1f8797 --- /dev/null +++ b/Enums/allureAttchementType_enum.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/30 13:32 +# @Author : 余少琪 + +from enum import Enum + + +class AllureAttachmentType(Enum): + """ + allure 报告的文件类型枚举 + """ + TEXT = "txt" + CSV = "csv" + TSV = "tsv" + URI_LIST = "uri" + + HTML = "html" + XML = "xml" + JSON = "json" + YAML = "yaml" + PCAP = "pcap" + + PNG = "png" + JPG = "jpg" + SVG = "svg" + GIF = "gif" + BMP = "bmp" + TIFF = "tiff" + + MP4 = "mp4" + OGG = "ogg" + WEBM = "webm" + + PDF = "pdf" + + @staticmethod + def attachment_types(): + return list(map(lambda c: c.value, AllureAttachmentType)) + diff --git a/Enums/assertType_enum.py b/Enums/assertType_enum.py new file mode 100644 index 0000000..cfc16d6 --- /dev/null +++ b/Enums/assertType_enum.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/29 18:03 +# @Author : 余少琪 + +from enum import Enum + + +class AssertType(Enum): + EQUAL = "==" + NOTEQUAL = "!=" + IN = "IN" + NO_TIN = "NOTIN" diff --git a/Enums/dependentType_enum.py b/Enums/dependentType_enum.py new file mode 100644 index 0000000..b899dc9 --- /dev/null +++ b/Enums/dependentType_enum.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/29 17:32 +# @Author : 余少琪 +from enum import Enum, unique + + +@unique +class DependentType(Enum): + """ + 数据依赖相关枚举 + """ + # 依赖响应中数据 + RESPONSE = 'response' + # 依赖请求中的数据 + REQUEST = 'request' + # 依赖sql中的数据 + SQL_DATA = 'sqlData' + diff --git a/Enums/notificationType_enum.py b/Enums/notificationType_enum.py new file mode 100644 index 0000000..cb64565 --- /dev/null +++ b/Enums/notificationType_enum.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/30 23:06 +# @Author : 余少琪 + +from enum import Enum + + +class NotificationType(Enum): + """ 自动化通知方式 """ + # 默认通知: 不发送 + DEFAULT = 0 + # 钉钉通知 + DING_TALK = 1 + # 微信通知 + WECHAT = 2 + # 邮箱通知 + EMAIL = 3 + # 飞书通知 + FEI_SHU = 4 diff --git a/Enums/requestType_enum.py b/Enums/requestType_enum.py new file mode 100644 index 0000000..5dc757b --- /dev/null +++ b/Enums/requestType_enum.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/29 17:42 +# @Author : 余少琪 + +from enum import Enum + + +class RequestType(Enum): + """ + request请求发送,请求参数的数据类型 + """ + # json 类型 + JSON = "JSON" + # PARAMS 类型 + PARAMS = "PARAMS" + # data 类型 + DATE = "DATE" + # 文件类型 + FILE = 'FILE' diff --git a/Enums/yamlData_enum.py b/Enums/yamlData_enum.py new file mode 100644 index 0000000..8795e5b --- /dev/null +++ b/Enums/yamlData_enum.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/29 17:51 +# @Author : 余少琪 +from enum import Enum + + +class YAMLDate(Enum): + """ + 测试用例相关字段 + """ + # host 配置 + HOST = 'host' + # 接口请求的url + URL = 'url' + # 请求方式 + METHOD = 'method' + # 请求头 + HEADER = 'headers' + # 请求类型 + REQUEST_TYPE = 'requestType' + # 是否执行 + IS_RUN = 'is_run' + # 请求参数 + DATA = 'data' + # 是否依赖用例 + DEPENDENCE_CASE = 'dependence_case' + # 依赖用例参数 + DEPENDENCE_CASE_DATA = 'dependence_case_data' + # 断言内容 + ASSERT = 'assert' + # sql内容 + SQL = 'sql' + # 用例ID + CASE_ID = 'case_id' + # jsonpath提取 + JSONPATH = 'jsonpath' + # 替换的内容 + REPLACE_KEY = 'replace_key' + # 依赖数据类型 + DEPENDENT_TYPE = 'dependent_type' + # 用例描述 + DETAIL = 'detail' + + + diff --git a/Files/companySewage.xlsx b/Files/companySewage.xlsx new file mode 100644 index 0000000..5399524 Binary files /dev/null and b/Files/companySewage.xlsx differ diff --git a/Files/test.png b/Files/test.png new file mode 100644 index 0000000..11fd652 Binary files /dev/null and b/Files/test.png differ diff --git a/Files/user_template_1648550100130.xlsx b/Files/user_template_1648550100130.xlsx new file mode 100644 index 0000000..c42dcbb Binary files /dev/null and b/Files/user_template_1648550100130.xlsx differ diff --git a/Files/排入水体名.png b/Files/排入水体名.png new file mode 100644 index 0000000..eedc9d3 Binary files /dev/null and b/Files/排入水体名.png differ diff --git a/README.md b/README.md index 4dedce9..6772143 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## 框架介绍 -本框架主要是基于 Python + pytest + allure + log + yaml + mysql + 钉钉通知 + Jenkins 实现的接口自动化框架。 +本框架主要是基于 Python + pytest + allure + log + yaml + mysql + redis + 钉钉通知 + Jenkins 实现的接口自动化框架。 * git地址: [https://gitee.com/yu_xiao_qi/pytest-auto-api](https://gitee.com/yu_xiao_qi/pytest-auto-api) * 项目参与者: 余少琪 @@ -9,11 +9,18 @@ 如果对您有帮助,请点亮 小星星 以表支持,谢谢 +![img.png](image/starts.png) -## 框架优势 +## 前言 +公司突然要求你做自动化,但是没有代码基础不知道怎么做?或者有自动化基础,但是不知道如何系统性的做自动化, +放在yaml文件中维护,不知道如何处理多业务依赖的逻辑? -本框架不收取任何费用, 其优势在于测试人员直接编写测试用例,运行框架可自动生成测试代码。 -框架支持多环境、多角色任意切换,支持接口响应断言以及数据库断言。 +那么这里 Gitte 中开源的自动化框架,将为你解决这些问题。 +框架主要使用 python 语言编写,结合 pytest 进行二次开发,用户仅需要在 yaml 文件中编写测试用例, +编写成功之后,会自动生成 pytest 的代码,零基础代码小白,也可以操作。 + +本框架支持多业务接口依赖,多进程执行,mysql 数据库断言和 接口响应断言,并且用例直接在yaml文件中维护,无需编写业务代码, +接口pytest框架生成allure报告,并且发送 企业微信通知/ 钉钉通知/ 邮箱通知/ 飞书通知,灵活配置。 ## 实现功能 @@ -29,35 +36,57 @@ * 多线程执行 ## 目录结构 - ├── Cache // 存放缓存文件 - ├── config // 配置 - │ ├── conf.yaml // 公共配置 - │ ├── setting.py // 环境路径存放区域 - ├── data // 测试用例数据 - ├── docs // 文档 - ├── lib // 对象层,用作于接口的调用 - ├── log // 日志层 - ├── report // 测试报告层 - ├── test_case // 测试用例代码 - ├── tool // 所有公共模块的封装 - │ └── allureDataControl.py // allure报告数据清洗 - │ └── assertControl.py // 断言模块 - │ └── cacheControl.py // 缓存模块 - │ └── dingtalkControl.py // 钉钉发送通知 - │ └── excelControl.py // 读取excel文件 - │ └── gettimeControl.py // 时间模块 - │ └── logControl.py // 日志模块 - │ └── logDecorator.py // 日志装饰器 - │ └── mysqlControl.py // 数据库模块 - │ └── regularControl.py // 正则模块 - │ └── requestControl.py // 请求模块 - │ └── runtimeControl.py // 响应时长统计模块 - │ └── sendmailControl.py // 发送邮件 - │ └── testcaseAutomaticControl.py // 自动生成测试代码 - │ └── yamlControl.py // yaml文件 - ├── Readme.md // help + ├── Cache // 存放缓存文件 + ├── config // 配置 + │ ├── conf.yaml // 公共配置 + │ ├── setting.py // 环境路径存放区域 + ├── data // 测试用例数据 + ├── Enums // 枚举层,用于存放项目中所需的枚举 + ├── File // 上传文件接口所需的文件存放区域 + ├── log // 日志层 + ├── report // 测试报告层 + ├── test_case // 测试用例代码 + ├── utils // 工具类 + │ └── assertUtils // 断言 + │ └── assertUtils .py + │ └── cacheUtils // 缓存处理模块 + │ └── cacheControl.py + │ └── redisControl.py + │ └── logUtils // 日志处理模块 + │ └── logControl.py + │ └── logDecoratrol.py // 日志装饰器 + │ └── runTimeDecoratrol.py // 统计用例执行时长装饰器 + │ └── mysqlUtils // 数据库模块 + │ └── get_sql_data.py + │ └── mysqlControl.py + │ └── noticUtils // 通知模块 + │ └── dingtalkControl.py // 钉钉通知 + │ └── feishuControl.py // 飞书通知 + │ └── sendmailControl.py // 邮箱通知 + │ └── weChatSendControl.py // 企业微信通知 + │ └── otherUtils // 其他工具类 + │ └── allureDate // allure封装 + │ └── allure_report_data.py // allure报告数据清洗 + │ └── allure_tools..py // allure 方法封装 + │ └── localIpControl.py // 获取本地IP + │ └── threadControl.py // 定时器类 + │ └── readFilesUtils // 文件操作 + │ └── caseAutomaticControl.py // 自动生成测试代码 + │ └── clean_files.py // 清理文件 + │ └── excelControl.py // 读写excel + │ └── get_all_files_path.py // 获取所有文件路径 + │ └── get_yaml_data_analysis.py // yaml用例数据清洗 + │ └── regularControl.py // 正则 + │ └── yamlControl.py // yaml文件读写 + │ └── recordingUtils // 代理录制 + │ └── mitmproxyContorl..py + │ └── requestsUtils + │ └── dependentCase.py // 数据依赖处理 + │ └── requestControl..py // 请求封装 + │ └── timeUtils + ├── Readme.md // help ├── pytest.ini - ├── run.py // 运行入口 + ├── run.py // 运行入口 ## 依赖库 @@ -99,140 +128,433 @@ xlutils==2.0.0 xlwt==1.3.0 -#### 安装Python、Pip环境,创建虚拟环境 -``` -一、安装Python环境 - -# 1、下载Python程序 -# Python包地址:https://www.python.org/ftp/python/ -wget https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tgz - -# 2、解压Python-3.8.5.tgz -tar -zxvf Python-3.8.5.tgz - -# 3、编译安装 -sudo mkdir /usr/local/python3.8.5 -cd Python-3.8.5 -sudo ./configure --prefix=/usr/local/python3.8.5 -sudo make && sudo make install - -# 4、建立软链接 -sudo ln -s /usr/local/python3.8.5/bin/python3 /usr/bin/python3 -sudo ln -s /usr/local/python3.8.5/bin/pip3 /usr/bin/pip3 - -# 5、验证安装 -python3 -V -pip3 -V - -二、安装虚拟环境、创建虚拟环境 -# 1、安装虚拟环境virtualenv -yum install -y python-virtualenv - -# 2、创建虚拟环境 -# 在项目根目录创建虚拟环境 -virtualenv -p python3 venv - -# 3、激活虚拟环境 -source ./venv/bin/activate - -# 4、退出虚拟环境 -deactivate -``` - ## 安装教程 输入如下命令,安装本框架的所有第三方库依赖 pip install -r requirements.txt -## 使用说明 +## 用例中相关字段的介绍 -### config-->conf.yaml +![img.png](image/case_datas.png) -![img.png](images/config/conf.png) +上方截图,就是一个用例中需要维护的相关字段,下面我会对每个字段的作用,做出解释。 -首先是配置文件,这里主要存放了一个公共的配置数据,如项目名称、钉钉、邮箱、企业微信、数据库等相关的配置全部都在这里 -所有的字段,在conf.yaml中,都有相关的注释,自行修改即可。 +1、case_common: 这个公共参数的维护,方便后期如有需要新增的字段,可以添加在公共参数中, +目前只有三个:allureEpic、allureFeature、allureStory, +这三个都是allure报告需要用到的装饰器内容,后续自动生成 pytest 中 test_case 会用到这三个参数值。 +2、spu_apply_list_01: 用例ID,唯一 +3、host: 接口的域名: 填写规则如下 ${{host}},执行脚本时,会去读取conf.yaml 文件中配置域名 +4、url: 接口路径 +5、header: 请求头 +6、requestType: 请求参数类型,有json、file、params、data四种类型 +7、is_run: 是否执行,为空、或者 True 都会执行 +8、data: 请求参数,所有的请求参数,全部放在 data 下方 +9、dependence_case:判断该条用力,是否有依赖业务,如为空或者 false 则表示没有 +10、dependence_case_data:依赖用例中需要的相关数据(下方数据依赖示例中,会对该字段下方的内容,做详细介绍) +11、assert: 断言,支持判断sql、或者接口响应内容。 +12、sql:该用例中所需使用的sql -目前框架主要是用的企业微信通知,在用例执行成功之后发送通知,通知内容如下,可以根据公司主要使用的通讯工具自行更改。 -在公共方法中分别封装了钉钉通知、以及邮箱通知。 +### 如何发送get请求 +上方了解了用例的数据结构之后,下面我们开始编写第一个get请求方式的接口。 +首先,开始编写项目之后,我们在 conf.yaml 中配置项目的域名 -# 注意点: -# 之前为了小伙伴们拉下代码执行的时候不受影响,企业微信、钉钉、邮箱的通知配置的都是我的 -# 我发现很多拉代码的小伙伴这里配置都没改,所有的通知都发到我这里来了哦~~麻烦看到这里的小伙伴自己在conf.yaml改一下相关配置 +![img.png](image/conf.png) -![img.png](images/config/wechat.png) +域名配置好之后,我们来编写测试用例,在 data 文件下面,创建一个名称为 +spu_apply_list.yaml 的用例文件,内容如下 -如程序执行执行异常时,会自动收集错误信息,并将内容发送邮件。 - -![img.png](images/data/email.png) - -### config --> setting.py - -setting.py 文件主要是用来存放项目中所有文件的目录地址 - -更改过一些公用的配置之后,下面我们来开始编写自动化 - -### data 用来存放测试用例 - -![img.png](images/data/data.png) - -上方主要是测试用例,测试用例是整个自动化程序中非常重要的一部分,需要严格按照我上方图中的格式进行编写。 -下面我会对每个字段依次进行解释对应的作用。 - -- url: 请求接口的地址,${{MerchantHost}} 为接口的host,放在conf.yaml 文件中,可以更改成公司项目的host -- method: 请求方式,目前支持GET、POST、DELETE、PUT,本人公司目前设计到的请求方式只有这四种,如有需求可自行添加 -- detail: 用例描述,程序中未强制要求必填,但是最好是每个用例都填写上,打印日志以及生成代码的函数注释,都会依赖用例描述 -- header: 请求头 -- requestType: 必填,这个字段主要取决于你请求的是参数是以json、params、file、或者data的格式 -- data: 请求参数 - 如接口中需要的请求参数全部放在data中 -- allureEpic: 作用与allure装饰器,必填(如有多个测试用例,只需要写在第一个用例中就行) -- allureFeature: 作用于allure装饰器,必填(如有多个测试用例,只需要写在第一个用例中就行) -- resp: 响应断言相关的数据 - - 响应接口的参数字段(如code): code,就是接口的响应状态码,这些参数都是自己加的。 - - jsonpath: 这里获取到对应的接口数据,主要使用到了jsonpath。如果有不了这一块的,大家可以看我的博客:https://blog.csdn.net/weixin_43865008/article/details/118371620 - - value: 预期值,这里会根据你前面jsonpath中获取到的响应数据,然后和你添加的预期值进行断言。如果断言失败,会打印对应的日志信息,以及allure测试报告中也会呈现这条用例的失败状态 - - type: 断言的类型,如判断是否相等,则使用”==“,或者”!=“,则表示内容不相等,”IN“则表示预期值是否在响应值中,对应的还有"NOTIN" - - AssertType: 目前自动化支持两种断言类型,接口响应断言和数据库断言。如果是接口响应断言,则AssertType的值可不填,如果值为"SQL"的话,则走数据库断言。为sql的时候,sql查询出来的数据类型是字典类型,因此value值会从sql查询出来的字段中使用jsonpath的形式读取sql查询出来的数据 - - 如有多个数据,则可像上方图中一样,创建多个字段 - - sql: sql 是以 LIST 的类型存储的,可以将我们这个接口需要依赖的sql语句全部放在这里,程序中会循环查询出sql中的所有语句,并且返回数据库中的值,从而与接口响应的值做匹配。(这里也是对于sql多表联查不太会的朋友的福音。如果不会多表联查的话,可以编写单表sql,程序中会将所有单表的数据内容全部查询出来) -- 接口中如有多条测试用例,则以上方格式为例,添加多个即可。 - -## lib---> xxx.py - -假设我们按照上方图中的格式内容,创建了一个用例创建成功之后yaml文件的用例,创建之后下面我们来生成自动化脚本,执行第一条用例。 -![img.png](images/lib/writecase.png) - -首先,我们找到tools目录下的 testcaseAutomaticControl.py 文件,然后执行这里的代码 - -执行成功之后,我们可以看到lib和test_case目录下,会生成一个和创建用例yaml文件名称一模一样的py文件,test_case名称会以test_开头 -内容如下: -![img.png](images/lib/lib.png) + # 公共参数 + case_common: + allureEpic: 电商平台端 + allureFeature: 审核中心 + allureStory: 商品审核列表 -下面我们就可以开始执行我们的测试用例了,这里生成的文件,主要类似于我们自动化模型中的PO模型,生成的page + + spu_apply_list_01: + host: ${{host}} + url: /api/v1/work/spu/approval/spuList + method: GET + detail: 查看商品审核列表 + headers: + Content-Type: application/json;charset=UTF-8 + token: work_login_init + # 请求的数据,是 params 还是 json、或者file + requestType: params + # 是否执行,空或者 true 都会执行 + is_run: False + data: + spuType: 1 + pageNum: 1 + pageSize: 10 + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: + # 依赖的数据 + dependence_case_data: + assert: + code: + jsonpath: $.code + type: == + value: 200 + AssertType: + sql: -执行之后,我们可以看到下方详细的请求日志信息,方便我们进行用例调试(lie层只是作用域单个接口的调试,如果需要多接口跑业务的话,直接到test_case层去做即可) +get请求我们 requestType 写的是params,这样发送请求时,我们会将请求参数拼接中url中,最终像服务端发送请求的地址格式会为: -![img.png](images/lib/runcase.png) + ${{host}}/api/v1/work/spu/approval/spuList?supType=1&pageNum=1&pageSize=10 -test_case --> test_apply_verifycode.py +### 如何发送post请求 -__用例调试成功之后,下面我们进入编写用例脚本阶段,主要内容如下:__ + # 公共参数 + case_common: + allureEpic: 盲盒APP + allureFeature: 登录模块 + allureStory: 获取登录验证码 + + send_sms_code_01: + host: ${{host}} + url: /mobile/sendSmsCode + method: POST + detail: 正常获取登录验证码 + headers: + appId: '23132' + masterAppId: masterAppId + Content-Type: application/json;charset=UTF-8 + # 请求的数据,是 params 还是 json、或者file + requestType: json + # 是否执行,空或者 true 都会执行 + is_run: + data: + phoneNumber: "180xxxx9278" + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: False + # 依赖的数据 + dependence_case_data: + assert: + code: + jsonpath: $.code + type: == + value: '00000' + AssertType: + success: + jsonpath: $.success + type: == + value: true + AssertType: + + sql: + +这里post请求,我们需要请求的数据格式是json格式的,那么requestType 则填写为json格式。包括 PUT/DELETE/HEAD 请求的数据格式都是一样的,唯一不同的就是需要配置 reuqestType,如果需要请求的参数是json格式,则requestType我们就填写json,如果是url拼接的形式,我们就填写 params -![img.png](images/testcases/img.png) +### 如何测试上传文件接口 -其中代码中关于pytest的相关内容,网上的资料有非常多,并且非常详情,这里不做赘述。 +首先,我们将所有需要测试的文件,全部都放在 files 文件夹中 +![img.png](image/files.png) -所有的用例内容,格式都为统一的,目前只能生成单接口的业务用例,如果需要接口执行的话,还需要在case层调用对应业务的接口 + requestType: file + # 是否执行,空或者 true 都会执行 + is_run: + data: + file: + # file 直接写文件名称 + files:排入水体名.png -用例添加完成之后,执行run.py,程序会执行所有文件的用例,并且生成测试报告,发送钉钉通知。 + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: False + +在yaml文件中,我们需要注意两个地方,主要是用例中的requestType、和 filename 字段: +1、requestType: 上传文件,我们需要更改成 file +2、filename 参数名称: 上传文件,我们只需要填写files文件夹下的文件名称即可,程序在发送请求时,会去识别文件 + +### 多业务逻辑,如何编写测试用例 +多业务这一块,我们拿个简单的例子举例,比如登录场景,在登陆之前,我们需要先获取到验证码。 + +![img.png](image/send_sms_code.png) + +![img.png](image/login.png) + +首先,我们先创建一个 get_send_sms_code.yaml 的文件,编写一条发送验证码的用例 + + # 公共参数 + case_common: + allureEpic: 盲盒APP + allureFeature: 登录模块 + allureStory: 获取登录验证码 + + send_sms_code_01: + host: ${{host}} + url: /mobile/sendSmsCode + method: POST + detail: 正常获取登录验证码 + headers: + appId: '23132' + masterAppId: masterAppId + Content-Type: application/json;charset=UTF-8 + # 请求的数据,是 params 还是 json、或者file + requestType: json + # 是否执行,空或者 true 都会执行 + is_run: + data: + phoneNumber: "180****9278" + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: False + # 依赖的数据 + dependence_case_data: + assert: + code: + jsonpath: $.code + type: == + value: '00000' + AssertType: + success: + jsonpath: $.success + type: == + value: true + AssertType: + + sql: + +编写好之后,我们在创建一个 login.yaml 文件 + + # 公共参数 + case_common: + allureEpic: 盲盒APP + allureFeature: 登录模块 + allureStory: 登录 + + login_02: + host: ${{host}} + url: /login/phone + method: POST + detail: 登录输入错误的验证码 + headers: + appId: '23132' + masterAppId: masterAppId + Content-Type: application/json;charset=UTF-8 + # 请求的数据,是 params 还是 json、或者file + requestType: json + # 是否执行,空或者 true 都会执行 + is_run: + data: + phoneNumber: 18014909278 + code: + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: True + # 依赖的数据 + dependence_case_data: + - case_id: send_sms_code_02 + dependent_data: + - dependent_type: response + jsonpath: $.code + replace_key: $.data.code + + assert: + code: + jsonpath: $.code + type: == + value: '00000' + AssertType: + sql: + +其中处理多业务的核心区域,主要在这里: + + dependence_case: True + # 依赖的数据 + dependence_case_data: + - case_id: send_sms_code_02 + dependent_data: + - dependent_type: response + jsonpath: $.code + replace_key: $.data.code + +首先,我们 dependence_case 需要设置成 True,并且在下面的 dependence_case_data 中设计相关依赖的数据。 + +1、case_id:上方场景中,我们登录需要先获取验证码,因此依赖的case_id 就是发送短信验证码的 case_id :send_sms_code_02 +2、dependent_type:我们依赖的是获取短信验证码接口中的响应内容,因此这次填写的是 response +3、jsonpath: 通过jsonpath 提取方式,提取到短信验证码中的验证码内容 +4、replace_key:拿到验证码之后,我们将本条用例中的data中的code参数,那么我们使用jsonpath的方式,进行替换 $.data.code + +### 多业务逻辑,需要依赖同一个接口中的多个数据 + dependence_case_data: + - case_id: send_sms_code_02 + dependent_data: + # 提取接口响应的code码 + - dependent_type: response + jsonpath: $.code + replace_key: $.data.code + # 提取接口响应的accessToken + - dependent_type: response + jsonpath: $.data.accessToken + # 替换请求头中的accessToken + replace_key: $.headers.accessToken -### 关于框架未来功能的规划 +如上方示例,可以添加多个 dependent_type -1、计划后期多接口业务逻辑,也统一放在yaml文件中维护,并且生成对应业务逻辑的相关代码 -2、自动生成代码的功能,计划通过多线程实现 +### 多业务逻辑,需要依赖不同接口的数据 +假设我们需要获取 send_sms_code_01、get_code_01两个接口中的数据,用例格式如下 + + dependence_case: True + # 依赖的数据 + dependence_case_data: + - case_id: send_sms_code_01 + dependent_data: + # 提取接口响应的code码 + - dependent_type: response + jsonpath: $.code + replace_key: $.data.code + - case_id: get_code_01 + dependent_data: + # 提取接口响应的code码 + - dependent_type: response + jsonpath: $.code + replace_key: $.data.code + +### 用例中需要依赖登录的token,如何设计 + +首先,为了防止重复请求调用登录接口,pytest中的 conftest.py 提供了热加载机制,看上方截图中的代码,我们需要在 conftest.py 提前编写好登录的代码。 + +![img.png](image/conftest.png) + +如上方代码所示,我们会先去读取login.yaml文件中的用例,然后执行获取到响应中的token,然后 编写 Cache('work_login_init').set_caches(token),将token写入缓存中,其中 work_login_init 是缓存名称。 + +编写好之后,我们会在 requestControl.py 文件中,读取缓存中的token,如果该条用例需要依赖token,则直接进行内容替换。 + +![img.png](image/token.png) + +这里在编写用例的时候,token 填写我们所编写的缓存名称即可。 + +### 用例中如何生成随机数据 + +比如我们有些特殊的场景,可能会涉及到一些定制化的数据,每次执行数据,需要按照指定规则随机生成。 + +![img.png](image/randoms.png) + +如上图所示,我们用例中的 reason 审核原因后方,需要展示审核的当前时间。那么我们首先需要封装一个获取当前时间的方法 + +![img.png](image/regular.png) + +那么我们就在 regularControl.py 文件中,编写 get_time 的方法。编写好之后,在用例中编写规则如下: + + reason: 审核时间${{get_time}} +使用 ${{函数名称}}的方法,程序调用时,会生成当前时间。在regularControl.py 文件中,我还封装了一些常用的随机数,如随机生成男生姓名、女生姓名、身份证、邮箱、手机号码之类的,方便大家使用。 如,随机生成邮箱,我们在用例中编写的格式为 ${{get_email}} 。 + +其他所需随机生成的数据,可在文件中自行添加。 + + +### 用例中如何进行接口断言和数据库断言 + +假设现在我需要测试一个报表统计的数据,该接口返回了任务的处理时长 和 处理数量。功能如下截图所示: + +![img.png](image/question_coun.png) + +假设下方是我们拿到接口响应的数据内容: + + {"code": 200, "times": 155.91, "counts": 9} + +这个时候,我们需要判断该接口返回的数据是否正确,就需要编写sql,对响应内容进行校验。 + +![img.png](image/sql.png) + +因此我们编写了如上sql,查出对应的数据,那么用例中编写规则如下,下方我们分别断言了两个内容,一个是对接口的响应code码进行断言,一个是断言数据库中的数据。 + + + assert: + code: + jsonpath: $.code + type: == + value: 200 + # 断言接口响应时,可以为空 + AssertType: + do_time: + # jsonpath 拿到接口响应的数据 + jsonpath: $.times + type: == + # sql 查出来的数据,是字典类型的,因此这里是从字段中提取查看出来的字段 + value: $.do_time + # 断言sql的时候,AssertType 的值需要填写成 SQL + AssertType: SQL + question_counts: + jsonpath: $.counts + type: == + # + value: $.question_counts + # 断言sql的时候,AssertType 的值需要填写成 SQL + AssertType: SQL + sql: + - select * from test_goods where shop_id = 515 + +我们分别对用例的数据进行讲解,首先是响应断言, 编写规则如下 + + code: + # 通过jsonpath获取接口响应中的code {"code": 200, "times": 155.91, "counts": 9} + jsonpath: $.code + type: == + value: 200 + # 断言接口响应时,可以为空 + AssertType: + +下面是对sql进行断言 + + question_counts: + # 断言接口响应的问题上报数量counts {"code": 200, "times": 155.91, "counts": 9} + jsonpath: $.counts + type: == + # 查询sql,我们数据库查到的数据是一个字段,数据是这样的:{question_counts: 13, do_time: 1482.70}, 这里我们通过 jsonpath获取question_counts + value: $.question_counts + # 断言sql的时候,AssertType 的值需要填写成 SQL + AssertType: SQL + sql: + - SELECT round( sum(( UNIX_TIMESTAMP( filing_time )- UNIX_TIMESTAMP( report_time )) / 60 ) / 60, 2 ) AS do_time, count( id ) AS question_counts FROM fl_report_info WHERE state IN ( 1, 3 ) + +有些细心的小伙伴会发现,我们的sql,是列表类型的。这样就意味这,我们的sql可以同时编写多条,这样会对不会编写多表联查的小伙伴比较友好,可以进行单表查询,获取我们需要的数据。 + + sql: + - select * from users; + - select * from goods; + +### 自动生成test_case层代码 + +小伙伴们在编写好 yaml 用例之后,可以直接执行 caseAutomaticControl.py ,会跟你设计的测试用例,生成对应的代码。 + +![img.png](image/write_test_case.png) + +### 发送钉钉通知通知 +![img.png](image/dingding.png) + +### 发送企业微信通知 +![img.png](image/wechart.png) + +### 日志打印装饰器 + +![img.png](image/log.png) + +在requestControl.py中,我单独封装了一个日志装饰器,需要的小伙伴可以不用改动代码,直接使用,如果不需要,直接注释,或者改成False。控制台将不会有日志输出 + +### 统计用例运行时长 +![img.png](image/run_times.png) + +同样,这里封装了一个统计用例运行时长的装饰器,使用改装饰器前,需要先进行导包 + + from utils.logUtils.runTimeDecoratorl import execution_duration +导入之后,调用改装饰器,装饰器中填写的用例执行时长,以毫秒为单位,如这里设置的2000ms,那么如果该用例执行大于2000ms,则会输出一条告警日志。 + + @execution_duration(2000) + +### 生成allure报告 +我们直接运行主程序 run.py ,运行完成之后,就可以生成漂亮的allure报告啦~ + +![img.png](image/allure.png) + +![img.png](image/allure2.png) + +### 其他 + +本框架为2.0升级版本,升级之后的功能,现在基本上都是在yaml中维护用例,无需测试人员编写代码, +和 1.0版本的区别在于,1.0版本还需要测试人员手动编写多业务逻辑的代码,需要有一定基础编码的能力 + +但是1.0版本,同样也可以自动生成代码,yaml中维护数据,对相对简单,如果偏于yaml简单维护的同学,可以切换查看1.0分支 +下方是1.0分支的操作文档:[点我查看](https://blog.csdn.net/weixin_43865008/article/details/121903028?spm=1001.2014.3001.5502) ******************************************************* diff --git a/config/__init__.py b/config/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/config/__pycache__/__init__.cpython-38.pyc b/config/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 4a22e9e..0000000 Binary files a/config/__pycache__/__init__.cpython-38.pyc and /dev/null differ diff --git a/config/__pycache__/setting.cpython-38.pyc b/config/__pycache__/setting.cpython-38.pyc deleted file mode 100644 index c1d144e..0000000 Binary files a/config/__pycache__/setting.cpython-38.pyc and /dev/null differ diff --git a/config/__pycache__/setting.cpython-39.pyc b/config/__pycache__/setting.cpython-39.pyc new file mode 100644 index 0000000..a512cd1 Binary files /dev/null and b/config/__pycache__/setting.cpython-39.pyc differ diff --git a/config/conf.yaml b/config/config.yaml similarity index 77% rename from config/conf.yaml rename to config/config.yaml index 4dc4150..0c492ab 100644 --- a/config/conf.yaml +++ b/config/config.yaml @@ -2,15 +2,17 @@ ProjectName: - 余少琪的框架 - +Env: 测试环境 # 测试人员名称,作用于自动生成代码的作者,以及发送企业微信、钉钉通知的测试负责人 -TestName: 余少琪 +TesterName: 余少琪 # 域名1 -Host: https://redisdatarecall.csdn.net +host: https://www.baidu.com # 域名随便写的,记得修改 +app_host: # 域名2 work: -# 报告通知类型:1:钉钉 2:企业微信通知 3、邮箱 +# 报告通知类型:0: 不发送通知 1:钉钉 2:企业微信通知 3、邮箱通知 4、飞书通知 NotificationType: 2 # 注意点: @@ -24,12 +26,11 @@ DingTalk: # 数据库相关配置 MySqlDB: - # 数据库开关 switch: False host: - user: + user: dev password: - db: test_obp_data + db: # 企业通知的相关配置 @@ -39,6 +40,10 @@ WeChat: email: send_user: 1603453211@qq.com email_host: smtp.qq.com - stmp_key: rzuabbobadbuhadc + stamp_key: rzuabbobadbuhadc # 收件人 send_list: 1603453211@qq.com + +# 飞书通知 +FeiShuTalk: + webhook: \ No newline at end of file diff --git a/config/setting.py b/config/setting.py index fe406c2..16a700d 100644 --- a/config/setting.py +++ b/config/setting.py @@ -28,23 +28,16 @@ class ConfigHandler: # 项目路径 root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - # 测试数据路径 - date_path = os.path.join(root_path, 'data' + _SLASH + "Merchant" + _SLASH + "UserLogin") - - merchant_data_path = os.path.join(root_path, 'data' + _SLASH) - + # 用例路径 + case_path = os.path.join(root_path, 'test_case' + _SLASH) + # 测试用例数据路径 data_path = os.path.join(root_path, 'data' + _SLASH) cache_path = os.path.join(root_path, 'Cache' + _SLASH) + if not os.path.exists(cache_path): + os.mkdir(cache_path) - case_path = os.path.join(root_path, 'test_case' + _SLASH) - - # 测试报告路径 - report_path = os.path.join(root_path, 'report') - - json_path = os.path.join(root_path, 'data' + _SLASH + 'data.json') - - log_path = os.path.join(root_path + _SLASH + 'logs') + log_path = os.path.join(root_path, 'logs' + _SLASH + 'log.log') info_log_path = os.path.join(root_path, 'logs' + _SLASH + 'info.log') @@ -52,23 +45,20 @@ class ConfigHandler: warning_log_path = os.path.join(root_path, 'logs' + _SLASH + 'warning.log') - if not os.path.exists(report_path): - os.mkdir(report_path) + config_path = os.path.join(root_path, 'config' + _SLASH + 'config.yaml') - config_path = os.path.join(root_path, 'config' + _SLASH + 'conf.yaml') + file_path = os.path.join(root_path, 'Files' + _SLASH) - token_yaml_path = os.path.join(root_path, 'data' + _SLASH + 'token.yaml') - - excel_path = os.path.join(root_path, 'data' + _SLASH) + # 测试报告路径 + report_path = os.path.join(root_path, 'report') # lib 存放po文件 lib_path = os.path.join(root_path, "lib" + _SLASH) - temp_path = os.path.join(root_path, 'report' + _SLASH + 'tmp') - if not os.path.exists(temp_path): - os.mkdir(temp_path) - html_path = os.path.join(root_path, 'report' + _SLASH + 'html') + # temp_path = os.path.join(root_path, 'report' + _SLASH + 'tmp') + # if not os.path.exists(temp_path): + # os.mkdir(temp_path) if __name__ == '__main__': - print(ConfigHandler.temp_path) \ No newline at end of file + print(ConfigHandler.cache_path) diff --git a/data/Login/login.yaml b/data/Login/login.yaml new file mode 100644 index 0000000..ddb527a --- /dev/null +++ b/data/Login/login.yaml @@ -0,0 +1,32 @@ +# 公共参数 +case_common: + allureEpic: 电商平台端 + allureFeature: 登录模块 + allureStory: 正常登录 + +login: + host: ${{host}} + url: /api/v1/work/user/loginByPassword + method: POST + detail: 正常登录 + headers: + Content-Type: application/json;charset=UTF-8 + # 请求的数据,是 params 还是 json、或者file + requestType: json + # 是否执行,空或者 true 都会执行 + is_run: True + data: + param: + phone: '13300000000' + password: '123456' + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: False + # 依赖的数据 + dependence_case_data: + assert: + code: + jsonpath: $.code + type: == + value: 200 + AssertType: + sql: diff --git a/data/WorkApplyCenter/__init__.py b/data/WorkApplyCenter/__init__.py new file mode 100644 index 0000000..8a1b785 --- /dev/null +++ b/data/WorkApplyCenter/__init__.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/30 14:56 +# @Author : 余少琪 +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from config.setting import ConfigHandler + +TestData = CaseData(ConfigHandler.data_path + r'WorkApplyCenter/sup_apply_list.yaml').case_process() +print(TestData) +# print([i for i in TestData]) +is_run = [i['is_run'] for i in TestData] +print(is_run) \ No newline at end of file diff --git a/data/WorkApplyCenter/batchDisable.yaml b/data/WorkApplyCenter/batchDisable.yaml new file mode 100644 index 0000000..fda6cf2 --- /dev/null +++ b/data/WorkApplyCenter/batchDisable.yaml @@ -0,0 +1,31 @@ +# 公共参数 +case_common: + allureEpic: 电商平台 + allureFeature: 文件模块 + allureStory: PATCH + +batchDisable_01: + host: {{host}} + url: /adpt/advert/adplan/batchDisable + method: PATCH + detail: 测试PATCH接口 + headers: + Content-Type: application/json;charset=UTF-8 + Authorization: work_login_init + # 请求的数据,是 params 还是 json、或者file + requestType: json + # 是否执行,空或者 true 都会执行 + is_run: Fasle + data: + + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: False + # 依赖的数据 + dependence_case_data: + assert: + code: + jsonpath: $.code + type: == + value: 200 + AssertType: + sql: diff --git a/data/WorkApplyCenter/spu_apply.yaml b/data/WorkApplyCenter/spu_apply.yaml new file mode 100644 index 0000000..1942063 --- /dev/null +++ b/data/WorkApplyCenter/spu_apply.yaml @@ -0,0 +1,41 @@ +# 公共参数 +case_common: + allureEpic: 电商平台端 + allureFeature: 审核中心 + allureStory: 商品审核 + +spu_apply_01: + host: ${{host}} + url: /api/v1/work/spu/approval/pass + method: PUT + detail: 正常审核商品(测试一个接口依赖多个数据) + headers: + Content-Type: application/json;charset=UTF-8 + token: work_login_init + # 请求的数据,是 params 还是 json、或者file + requestType: json + # 是否执行,空或者 true 都会执行 + is_run: False + data: + applyId: + reason: 审核时间${{get_time}} + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: True + # 依赖的数据 + dependence_case_data: + - case_id: spu_apply_list_01 + dependent_data: + - dependent_type: response + jsonpath: $.data.data.[0].applyId + replace_key: $.data.applyId + - dependent_type: request + jsonpath: $.detail + replace_key: $.data.reason + assert: + code: + jsonpath: $.code + type: == + value: 200 + AssertType: + sql: + - select * from test_goods where shop_id = 515 diff --git a/data/WorkApplyCenter/sup_apply_list.yaml b/data/WorkApplyCenter/sup_apply_list.yaml new file mode 100644 index 0000000..78a352a --- /dev/null +++ b/data/WorkApplyCenter/sup_apply_list.yaml @@ -0,0 +1,34 @@ +# 公共参数 +case_common: + allureEpic: 电商平台端 + allureFeature: 审核中心 + allureStory: 商品审核列表 + + +spu_apply_list_01: + host: ${{host}} + url: /api/v1/work/spu/approval/spuList + method: GET + detail: 查看商品审核列表 + headers: + Content-Type: application/json;charset=UTF-8 + token: work_login_init + # 请求的数据,是 params 还是 json、或者file + requestType: params + # 是否执行,空或者 true 都会执行 + is_run: False + data: + spuType: 1 + pageNum: 1 + pageSize: 10 + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: + # 依赖的数据 + dependence_case_data: + assert: + code: + jsonpath: $.code + type: == + value: 200 + AssertType: + sql: diff --git a/data/WorkApplyCenter/work_apply_good_detail.yaml b/data/WorkApplyCenter/work_apply_good_detail.yaml new file mode 100644 index 0000000..090b7c3 --- /dev/null +++ b/data/WorkApplyCenter/work_apply_good_detail.yaml @@ -0,0 +1,42 @@ +# 公共参数 +case_common: + allureEpic: 电商平台端 + allureFeature: 审核中心 + allureStory: 商品审核详情 + +spuApplyDetails_01: + host: ${{host}} + url: /api/v1/work/spu/approval/spuApplyDetails/$url_param{good_id} + method: GET + detail: 查看商品审核详情 + headers: + Content-Type: application/json;charset=UTF-8 + token: work_login_init + # 请求的数据,是 params 还是 json、或者file\date + requestType: json + # 是否执行,空或者 true 都会执行 + is_run: False + data: + auth: + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: True + # 依赖的数据 + dependence_case_data: + - case_id: spu_apply_list_01 + dependent_data: + - dependent_type: response + jsonpath: $.data.data.[0].applyId + replace_key: $url_param{good_id} + - case_id: login_01 + dependent_data: + - dependent_type: response + jsonpath: $.data.data.[0].token + replace_key: $.data.auth + + assert: + code: + jsonpath: $.code + type: == + value: 200 + AssertType: + sql: diff --git a/test_case/__init__.py b/data/__init__.py similarity index 70% rename from test_case/__init__.py rename to data/__init__.py index 7c59819..661e00e 100644 --- a/test_case/__init__.py +++ b/data/__init__.py @@ -1,4 +1,5 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/18 23:05 +# @Time : 2022/3/28 10:49 # @Author : 余少琪 + diff --git a/data/test_demo/DateDemo.yaml b/data/test_demo/DateDemo.yaml deleted file mode 100644 index 548a891..0000000 --- a/data/test_demo/DateDemo.yaml +++ /dev/null @@ -1,27 +0,0 @@ -- # 用例001 - url: ${{Host}}/recommend/get_head_word - method: POST - detail: 测试接口 - headers: - Content-Type: application/json;charset=UTF-8 - requestType: params - # 测试平台名称 - allureEpic: 这里是测试平台名称 - # 测试模块名称 - allureFeature: 这里是测试模块名称 - data: - # 请求类型:params 是以url拼接的形式请求,json则传的是json串 - bid: blog-121903028 - resp: - code: - jsonpath: $.status - type: == - value: 200 - AssertType: - msg: - jsonpath: $.msg - type: == - value: 查询成功 - AssertType: - - sql: diff --git a/data/uplpad_file_test/up_files.yaml b/data/uplpad_file_test/up_files.yaml new file mode 100644 index 0000000..cca339b --- /dev/null +++ b/data/uplpad_file_test/up_files.yaml @@ -0,0 +1,36 @@ +# 公共参数 +case_common: + allureEpic: 婚奢汇 + allureFeature: 文件上传 + allureStory: 上传excel文件 + +upload_files_02: + host: {{host}} + url: /adpt/advert/mate/batchUploadMate + method: POST + detail: 测试上传文件接口 + headers: + Content-Type: application/json;charset=UTF-8 + Authorization: work_login_ini + # 请求的数据,是 params 还是 json、或者file + requestType: file + # 是否执行,空或者 true 都会执行 + is_run: + data: + file: + files: test.png + # 是否有依赖业务,为空或者false则表示没有 + data: + uids: vc-upload-1649224175138-20 + params: + test: 1 + dependence_case: + # 依赖的数据 + dependence_case_data: + assert: + code: + jsonpath: $.code + type: == + value: 1011006 + AssertType: + sql: diff --git a/data/uplpad_file_test/upload_files.yaml b/data/uplpad_file_test/upload_files.yaml new file mode 100644 index 0000000..c7e47f7 --- /dev/null +++ b/data/uplpad_file_test/upload_files.yaml @@ -0,0 +1,32 @@ +# 公共参数 +case_common: + allureEpic: 婚奢汇 + allureFeature: 文件上传 + allureStory: 上传excel文件 + +upload_files_01: + host: http://parkyz.kkx88.cn + url: /api/biz/company/importData + method: POST + detail: 测试上传文件接口 + headers: + Content-Type: application/json;charset=UTF-8 + Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjA1ZTc3ZDRiLWU3NWEtNGMyNi04NjA1LTI4M2Q3ZjdlNWNmZSJ9.2htV4vh5KxR9jEDltfifiwZUPd1OYrwLRXRLM2K1AEgoY-jTCn9z1m5aLPmpIIf2dL5YoSEbyxmGT9Pm1CwzMg + # 请求的数据,是 params 还是 json、或者file + requestType: file + # 是否执行,空或者 true 都会执行 + is_run: + data: + file: + file: companySewage.xlsx + # 是否有依赖业务,为空或者false则表示没有 + dependence_case: False + # 依赖的数据 + dependence_case_data: + assert: + code: + jsonpath: $.code + type: == + value: 401 + AssertType: + sql: diff --git a/image/allure.png b/image/allure.png new file mode 100644 index 0000000..870b3c1 Binary files /dev/null and b/image/allure.png differ diff --git a/image/allure2.png b/image/allure2.png new file mode 100644 index 0000000..33ac08b Binary files /dev/null and b/image/allure2.png differ diff --git a/image/case_datas.png b/image/case_datas.png new file mode 100644 index 0000000..fecc37e Binary files /dev/null and b/image/case_datas.png differ diff --git a/image/conf.png b/image/conf.png new file mode 100644 index 0000000..2e0eb84 Binary files /dev/null and b/image/conf.png differ diff --git a/image/conftest.png b/image/conftest.png new file mode 100644 index 0000000..da6ccec Binary files /dev/null and b/image/conftest.png differ diff --git a/image/dingding.png b/image/dingding.png new file mode 100644 index 0000000..14794e9 Binary files /dev/null and b/image/dingding.png differ diff --git a/image/files.png b/image/files.png new file mode 100644 index 0000000..9ac82f1 Binary files /dev/null and b/image/files.png differ diff --git a/image/log.png b/image/log.png new file mode 100644 index 0000000..b90d178 Binary files /dev/null and b/image/log.png differ diff --git a/image/login.png b/image/login.png new file mode 100644 index 0000000..f021f84 Binary files /dev/null and b/image/login.png differ diff --git a/image/question_coun.png b/image/question_coun.png new file mode 100644 index 0000000..f5613f4 Binary files /dev/null and b/image/question_coun.png differ diff --git a/image/randoms.png b/image/randoms.png new file mode 100644 index 0000000..d523365 Binary files /dev/null and b/image/randoms.png differ diff --git a/image/regular.png b/image/regular.png new file mode 100644 index 0000000..d378d50 Binary files /dev/null and b/image/regular.png differ diff --git a/image/run_times.png b/image/run_times.png new file mode 100644 index 0000000..f646c7c Binary files /dev/null and b/image/run_times.png differ diff --git a/image/send_sms_code.png b/image/send_sms_code.png new file mode 100644 index 0000000..2d8fe2b Binary files /dev/null and b/image/send_sms_code.png differ diff --git a/image/sql.png b/image/sql.png new file mode 100644 index 0000000..cfe5240 Binary files /dev/null and b/image/sql.png differ diff --git a/image/starts.png b/image/starts.png new file mode 100644 index 0000000..efb36d6 Binary files /dev/null and b/image/starts.png differ diff --git a/image/token.png b/image/token.png new file mode 100644 index 0000000..b2a1b71 Binary files /dev/null and b/image/token.png differ diff --git a/image/wechart.png b/image/wechart.png new file mode 100644 index 0000000..ba7f8ac Binary files /dev/null and b/image/wechart.png differ diff --git a/image/write_test_case.png b/image/write_test_case.png new file mode 100644 index 0000000..afd6c28 Binary files /dev/null and b/image/write_test_case.png differ diff --git a/images/config/conf.png b/images/config/conf.png deleted file mode 100644 index 61f344c..0000000 Binary files a/images/config/conf.png and /dev/null differ diff --git a/images/config/wechat.png b/images/config/wechat.png deleted file mode 100644 index c4136e2..0000000 Binary files a/images/config/wechat.png and /dev/null differ diff --git a/images/data/data.png b/images/data/data.png deleted file mode 100644 index 694a12b..0000000 Binary files a/images/data/data.png and /dev/null differ diff --git a/images/data/email.png b/images/data/email.png deleted file mode 100644 index 8b13880..0000000 Binary files a/images/data/email.png and /dev/null differ diff --git a/images/group.png b/images/group.png deleted file mode 100644 index cd1d4e7..0000000 Binary files a/images/group.png and /dev/null differ diff --git a/images/img.png b/images/img.png deleted file mode 100644 index 68a583f..0000000 Binary files a/images/img.png and /dev/null differ diff --git a/images/lib/lib.png b/images/lib/lib.png deleted file mode 100644 index 772876a..0000000 Binary files a/images/lib/lib.png and /dev/null differ diff --git a/images/lib/runcase.png b/images/lib/runcase.png deleted file mode 100644 index 74d74a5..0000000 Binary files a/images/lib/runcase.png and /dev/null differ diff --git a/images/lib/writecase.png b/images/lib/writecase.png deleted file mode 100644 index 05ed22d..0000000 Binary files a/images/lib/writecase.png and /dev/null differ diff --git a/images/testcases/img.png b/images/testcases/img.png deleted file mode 100644 index 40e9798..0000000 Binary files a/images/testcases/img.png and /dev/null differ diff --git a/lib/__pycache__/DateDemo.cpython-38.pyc b/lib/__pycache__/DateDemo.cpython-38.pyc deleted file mode 100644 index 772a62a..0000000 Binary files a/lib/__pycache__/DateDemo.cpython-38.pyc and /dev/null differ diff --git a/lib/test_demo/DateDemo.py b/lib/test_demo/DateDemo.py deleted file mode 100644 index f67bba4..0000000 --- a/lib/test_demo/DateDemo.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2022-03-16 13:07:13 -# @Author : 余少琪 - - -from tools.requestControl import RequestControl -from tools.yamlControl import GetCaseData -from config.setting import ConfigHandler - - -class DateDemo(object): - @staticmethod - def dateDemo(inData): - """ - 测试接口 - :param inData: - :return: - """ - - resp = RequestControl().http_request(inData['method'], inData) - return resp - - -if __name__ == '__main__': - path = GetCaseData(ConfigHandler.data_path + r'test_demo\DateDemo.yaml').get_yaml_case_data()[0] - data = DateDemo().dateDemo(path) - print(data) \ No newline at end of file diff --git a/logs/__init__.py b/logs/__init__.py index c972d01..50cd2d8 100644 --- a/logs/__init__.py +++ b/logs/__init__.py @@ -1,4 +1,4 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/18 23:05 -# @Author : 余少琪 \ No newline at end of file +# @Time : 2022/3/28 10:49 +# @Author : 余少琪 diff --git a/logs/error.log b/logs/error.log deleted file mode 100644 index 11b7e1f..0000000 --- a/logs/error.log +++ /dev/null @@ -1,2 +0,0 @@ -%(levelname)-8s2022-02-21 18:37:52,617 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\error.log:conftest.py:94 执行失败用例数:1 -%(levelname)-8s2022-02-21 18:38:30,385 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\error.log:conftest.py:94 执行失败用例数:0 diff --git a/logs/error.log.2022-04-02 b/logs/error.log.2022-04-02 new file mode 100644 index 0000000..e2a6921 --- /dev/null +++ b/logs/error.log.2022-04-02 @@ -0,0 +1,8 @@ +%(levelname)-8s2022-04-02 20:11:02,465 C:\work\Study\pytest-auto-api3\logs\error.log:assertControl.py:57 断言失败, 预期值:200, 断言类型==, 实际值1011006 +%(levelname)-8s2022-04-02 22:38:57,192 C:\work\Study\pytest-auto-api3\logs\error.log:assertControl.py:111 JsonPath值获取失败$.code +%(levelname)-8s2022-04-02 22:39:56,756 C:\work\Study\pytest-auto-api3\logs\error.log:assertControl.py:111 JsonPath值获取失败$.code +%(levelname)-8s2022-04-02 22:45:55,163 C:\work\Study\pytest-auto-api3\logs\error.log:assertControl.py:115 JsonPath值获取失败$.code +%(levelname)-8s2022-04-02 22:46:21,310 C:\work\Study\pytest-auto-api3\logs\error.log:assertControl.py:115 JsonPath值获取失败$.code +%(levelname)-8s2022-04-02 23:02:12,628 C:\work\Study\pytest-auto-api3\logs\error.log:assertControl.py:61 断言失败, 预期值:200, 断言类型==, 实际值1011006 +%(levelname)-8s2022-04-02 23:45:41,734 C:\work\Study\pytest-auto-api3\logs\error.log:assertControl.py:61 断言失败, 预期值:200, 断言类型==, 实际值1011006 +%(levelname)-8s2022-04-02 23:59:33,188 C:\work\Study\pytest-auto-api3\logs\error.log:assertControl.py:61 断言失败, 预期值:200, 断言类型==, 实际值1011006 diff --git a/logs/info.log b/logs/info.log deleted file mode 100644 index e0847cc..0000000 --- a/logs/info.log +++ /dev/null @@ -1,45 +0,0 @@ -%(levelname)-8s2022-02-21 18:37:50,684 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:run.py:19 - _ _ _ _____ _ - __ _ _ __ (_) / \ _ _| |_ __|_ _|__ ___| |_ - / _` | '_ \| | / _ \| | | | __/ _ \| |/ _ \/ __| __| - | (_| | |_) | |/ ___ \ |_| | || (_) | | __/\__ \ |_ - \__,_| .__/|_/_/ \_\__,_|\__\___/|_|\___||___/\__| - |_| - 开始执行余少琪的框架项目... - -%(levelname)-8s2022-02-21 18:37:52,389 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:logDecorator.py:25 -================================================================================= -测试标题: 测试接口 -请求方式: POST -请求头: {'Content-Type': 'application/json;charset=UTF-8'} -请求路径: https://redisdatarecall.csdn.net/recommend/get_head_word -请求参数类型: params -请求内容: {'bid': 'blog-121903028'} -接口响应内容: {'status': 200, 'msg': '查询成功', 'content': ['自动化测试', 'yaml', 'pytest', 'gitee', 'jenkins'], 'error': False} -数据库断言数据: {'sql': None} -================================================================================= -%(levelname)-8s2022-02-21 18:37:52,391 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:assertControl.py:61 断言成功, 预期值:200, 断言类型==, 实际值200 -%(levelname)-8s2022-02-21 18:37:52,391 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:assertControl.py:61 断言成功, 预期值:查询成功, 断言类型==, 实际值查询成功 -%(levelname)-8s2022-02-21 18:37:52,617 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:91 执行用例总数: 1 -%(levelname)-8s2022-02-21 18:37:52,617 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:92 执行通过用例数:0 -%(levelname)-8s2022-02-21 18:37:52,620 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:96 执行异常用例数:0 -%(levelname)-8s2022-02-21 18:37:52,620 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:98 执行跳过用例数:0 -%(levelname)-8s2022-02-21 18:37:52,621 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:100 执行成功率: 成功率:0.00% -%(levelname)-8s2022-02-21 18:38:30,375 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:logDecorator.py:25 -================================================================================= -测试标题: 测试接口 -请求方式: POST -请求头: {'Content-Type': 'application/json;charset=UTF-8'} -请求路径: https://redisdatarecall.csdn.net/recommend/get_head_word -请求参数类型: params -请求内容: {'bid': 'blog-121903028'} -接口响应内容: {'status': 200, 'msg': '查询成功', 'content': ['自动化测试', 'yaml', 'pytest', 'gitee', 'jenkins'], 'error': False} -数据库断言数据: {'sql': None} -================================================================================= -%(levelname)-8s2022-02-21 18:38:30,377 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:assertControl.py:61 断言成功, 预期值:200, 断言类型==, 实际值200 -%(levelname)-8s2022-02-21 18:38:30,378 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:assertControl.py:61 断言成功, 预期值:查询成功, 断言类型==, 实际值查询成功 -%(levelname)-8s2022-02-21 18:38:30,384 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:91 执行用例总数: 1 -%(levelname)-8s2022-02-21 18:38:30,384 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:92 执行通过用例数:1 -%(levelname)-8s2022-02-21 18:38:30,385 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:96 执行异常用例数:0 -%(levelname)-8s2022-02-21 18:38:30,386 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:98 执行跳过用例数:0 -%(levelname)-8s2022-02-21 18:38:30,386 C:\Users\hzxy\PycharmProjects\py_auto_demo\logs\info.log:conftest.py:100 执行成功率: 成功率:100.00% diff --git a/logs/info.log.2022-04-03 b/logs/info.log.2022-04-03 new file mode 100644 index 0000000..d2aed8d --- /dev/null +++ b/logs/info.log.2022-04-03 @@ -0,0 +1,681 @@ +%(levelname)-8s2022-04-02 20:11:00,689 C:\work\Study\pytest-auto-api3\logs\info.log:run.py:22 + _ _ _ _____ _ + __ _ _ __ (_) / \ _ _| |_ __|_ _|__ ___| |_ + / _` | '_ \| | / _ \| | | | __/ _ \| |/ _ \/ __| __| + | (_| | |_) | |/ ___ \ |_| | || (_) | | __/\__ \ |_ + \__,_| .__/|_/_/ \_\__,_|\__\___/|_|\___||___/\__| + |_| + 开始执行余少琪的框架项目... + +%(levelname)-8s2022-04-02 20:11:02,053 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532568b150a448f4bc8baed5ffb6ac0ab18', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '22d23bee6f847688736e315827b47227'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:11:02,464 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 测试patch请求方式 +请求方式: PATCH +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjEyNjU0NzY4OTA2NzI2NzI4MDgsImFjY291bnQiOiJzdXBlckFkbWluIiwidXVpZCI6IjJiOTNlNTNjLWRkM2QtNGM0MS05YjI2LTA1Y2NhM2JjMjNlOSIsInN1YiI6IjEyNjU0NzY4OTA2NzI2NzI4MDgiLCJpYXQiOjE2NDg2ODg2NTgsImV4cCI6MTY0ODc3NTA1OH0.640mDK2Eyid_KjSi0Ijei6VW6LYQZ7oYfGCgq4ajqehACzqfvaG4XJ5lqizRSVhidl7J1XTJZeBYVCjEe0GMdw'} +请求路径: http://39.105.186.77:8082/adpt/advert/adplan/batchDisable +请求内容: {'ids': ['1509343309343780875']} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 1011006, 'data': 'yn.luokung.wheel.auth.service.impl.AuthServiceImpl.checkToken(AuthServiceImpl.java:223)', 'message': '请求token错误', 'success': False} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:11:03,021 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532568b150a448f4bc8baed5ffb6ac0ab18'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637129578000, 'applyId': 105950, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637129578000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '不设置任务佣金,直接开启分类佣金', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3393, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 48, 'totalPage': 5}, 'success': True, 'traceId': '54ea87fb4b6a638f0aca4cc00817fb1a'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:11:03,131 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 正常审核商品 +请求方式: PUT +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532568b150a448f4bc8baed5ffb6ac0ab18'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/pass +请求内容: {'applyId': 105950, 'reason': '正常审核商品'} +依赖测试用例: [{'case_id': 'spu_apply_list_01', 'dependent_data': [{'dependent_type': 'response', 'jsonpath': '$.data.data.[0].applyId', 'replace_key': '$.data.applyId'}, {'dependent_type': 'request', 'jsonpath': '$.detail', 'replace_key': '$.data.reason'}]}] +接口响应内容: {'code': 200, 'success': True} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:11:03,302 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532568b150a448f4bc8baed5ffb6ac0ab18'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '6e3c33c1c575d24e0287d284356110e4'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:11:03,498 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532568b150a448f4bc8baed5ffb6ac0ab18'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '264f3bbe2ba5d480337228be64b7ad19'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:11:03,606 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532568b150a448f4bc8baed5ffb6ac0ab18'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '7201f809d26595eb18ff4a0b0fb842a8'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:15:12,814 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75326b9220eaa6a442eb81955a8df2ea007c', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '6853f733c570852d34b5b20dea5bd014'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:15:13,259 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '75326b9220eaa6a442eb81955a8df2ea007c'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '50ce1317710875c909d4bc050ca373ec'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:22:07,770 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:33 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '753273f9a9670e3d43feb7f86b821c6297b2', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '432021e633d8e56d3c55531c83e4e0a0'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 20:23:30,188 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75323ab1454709744758ac728e39823cbdc2', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '25034ddab20ebaad5bdcb45b487f95c1'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:25:32,044 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532eafb2b8ba5ff49b2a8c02c6bbdbb4fc5', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '11748e8d5e7f541e34f305099c36bc67'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:28:23,130 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '753243588a1566c9404989ff6649e3862fdb', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '0c2b41405beb634e1951a681d40d9bc7'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:28:23,742 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '753243588a1566c9404989ff6649e3862fdb'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '1fb513c7a1d86d57260993ef80d4fb28'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:31:03,771 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75326b6afdfc526143728bb7d3caf33405aa', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '405611fd489455d94196ca8e4f91438b'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:31:04,210 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '75326b6afdfc526143728bb7d3caf33405aa'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '4e038b9c115e8011012e10d1d0c535cc'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:31:55,493 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75329bbc8d7f2a3d413aa5eb427f64b86e29', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '50377a20b1ff3b1a20ff1fee12b223c0'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:31:55,944 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '75329bbc8d7f2a3d413aa5eb427f64b86e29'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '6c6c2c875898168b5dce099eb3c07123'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:34:43,776 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '753222f6d6ca659b4d2592c20020eb4d8d83', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '16e5077449a7d1f01ba07b1ae80c7f5b'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:35:06,956 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75329bd858281cb648299ba88af94e9900a7', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '6e288867a9ec390b428f101c33031460'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:35:55,615 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75320345080615934b8fbaec6eff12cd4487', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '089320ab78b22a7960f18abd05726594'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:38:56,869 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75320cbf785bbb6243c3bf25cf3b978ba80a', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '45764cf443e0aa674ea771f3191471e6'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:38:57,190 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '75320cbf785bbb6243c3bf25cf3b978ba80a'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {None: None} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:39:56,428 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532b5d525e736264ad2bd60f9ce1f2bfca4', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '7722eb89a40f6fdc784d9f38f0ea71ae'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:39:56,755 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b5d525e736264ad2bd60f9ce1f2bfca4'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {None: None} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:45:54,835 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532571a35e4a76547cbafee40ae6aed1c1a', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '7dc7cb21509adde35500bb61fefe8307'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:45:55,162 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532571a35e4a76547cbafee40ae6aed1c1a'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:46:20,971 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532b894ea7713564771974a161491b641c7', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '05d4b4285ebefed71551b21a3ab66d0e'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:46:21,309 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b894ea7713564771974a161491b641c7'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:46:52,515 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532d7eb8c831b3048d9b324056fefdf8a77', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '0763b63a9297c30b5c7173d77137730b'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:46:53,306 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532d7eb8c831b3048d9b324056fefdf8a77'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:47:44,497 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532c218f2c7ed984d1a9bc955628a1b798e', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '6e9c5d06c87371244839cafcd345ed74'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:47:45,047 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532c218f2c7ed984d1a9bc955628a1b798e'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:48:53,884 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75320e48f24595bc4c05a8313c9827ef36bc', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '06d0f1c3d6a145ce214154494446267f'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:48:54,292 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:34 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '75320e48f24595bc4c05a8313c9827ef36bc'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:54:17,607 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532b0cd0c63d9f74aa980bcd1e1f1a70326', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '78434337064f38ce59dc466475c30284'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:54:17,965 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b0cd0c63d9f74aa980bcd1e1f1a70326'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:55:17,758 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532e053aa889959436e8bf378bb1d640cb0', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '2221ea2b280072a80822b4b0d0ee2d37'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:55:18,087 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532e053aa889959436e8bf378bb1d640cb0'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:56:47,769 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '753263e5f81e3b40436d8b7ceffcdf791c5c', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '44e0ddf10de5c9c34741e185ca36e4c3'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:57:31,533 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532109233fa72ad486c97e471d6ff2d6204', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '6604d4bddb60b0ae2a954fcceb31f571'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:58:04,086 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '753238d8227812d14a93a7561e25c5a40e01', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '7647e82c49d11a503f75063fd21cb48f'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:58:04,727 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '753238d8227812d14a93a7561e25c5a40e01'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '3fc8f87abbe2d9cd4db4f10a70533ee6'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:59:32,388 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532858067c9c2224dfeb2e5020a15c1d138', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '3e175e7833db8acb67abf7bbd1b0b041'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:59:32,870 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532858067c9c2224dfeb2e5020a15c1d138'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '03e25872d742f0eb39915bab10672df1'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 22:59:47,625 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532b925b258a4c54a7a97e24f668727d0d5', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '4639345f3fcc76990052e402dfa4a2e9'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 23:02:11,373 C:\work\Study\pytest-auto-api3\logs\info.log:run.py:22 + _ _ _ _____ _ + __ _ _ __ (_) / \ _ _| |_ __|_ _|__ ___| |_ + / _` | '_ \| | / _ \| | | | __/ _ \| |/ _ \/ __| __| + | (_| | |_) | |/ ___ \ |_| | || (_) | | __/\__ \ |_ + \__,_| .__/|_/_/ \_\__,_|\__\___/|_|\___||___/\__| + |_| + 开始执行余少琪的框架项目... + +%(levelname)-8s2022-04-02 23:02:12,626 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 测试patch请求方式 +请求方式: PATCH +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjEyNjU0NzY4OTA2NzI2NzI4MDgsImFjY291bnQiOiJzdXBlckFkbWluIiwidXVpZCI6IjJiOTNlNTNjLWRkM2QtNGM0MS05YjI2LTA1Y2NhM2JjMjNlOSIsInN1YiI6IjEyNjU0NzY4OTA2NzI2NzI4MDgiLCJpYXQiOjE2NDg2ODg2NTgsImV4cCI6MTY0ODc3NTA1OH0.640mDK2Eyid_KjSi0Ijei6VW6LYQZ7oYfGCgq4ajqehACzqfvaG4XJ5lqizRSVhidl7J1XTJZeBYVCjEe0GMdw'} +请求路径: http://39.105.186.77:8082/adpt/advert/adplan/batchDisable +请求内容: {'ids': ['1509343309343780875']} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 1011006, 'data': 'yn.luokung.wheel.auth.service.impl.AuthServiceImpl.checkToken(AuthServiceImpl.java:223)', 'message': '请求token错误', 'success': False} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 23:42:23,522 C:\work\Study\pytest-auto-api3\logs\info.log:run.py:22 + _ _ _ _____ _ + __ _ _ __ (_) / \ _ _| |_ __|_ _|__ ___| |_ + / _` | '_ \| | / _ \| | | | __/ _ \| |/ _ \/ __| __| + | (_| | |_) | |/ ___ \ |_| | || (_) | | __/\__ \ |_ + \__,_| .__/|_/_/ \_\__,_|\__\___/|_|\___||___/\__| + |_| + 开始执行余少琪的框架项目... + +%(levelname)-8s2022-04-02 23:45:38,175 C:\work\Study\pytest-auto-api3\logs\info.log:run.py:22 + _ _ _ _____ _ + __ _ _ __ (_) / \ _ _| |_ __|_ _|__ ___| |_ + / _` | '_ \| | / _ \| | | | __/ _ \| |/ _ \/ __| __| + | (_| | |_) | |/ ___ \ |_| | || (_) | | __/\__ \ |_ + \__,_| .__/|_/_/ \_\__,_|\__\___/|_|\___||___/\__| + |_| + 开始执行余少琪的框架项目... + +%(levelname)-8s2022-04-02 23:45:41,734 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 测试patch请求方式 +请求方式: PATCH +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjEyNjU0NzY4OTA2NzI2NzI4MDgsImFjY291bnQiOiJzdXBlckFkbWluIiwidXVpZCI6IjJiOTNlNTNjLWRkM2QtNGM0MS05YjI2LTA1Y2NhM2JjMjNlOSIsInN1YiI6IjEyNjU0NzY4OTA2NzI2NzI4MDgiLCJpYXQiOjE2NDg2ODg2NTgsImV4cCI6MTY0ODc3NTA1OH0.640mDK2Eyid_KjSi0Ijei6VW6LYQZ7oYfGCgq4ajqehACzqfvaG4XJ5lqizRSVhidl7J1XTJZeBYVCjEe0GMdw'} +请求路径: http://39.105.186.77:8082/adpt/advert/adplan/batchDisable +请求内容: {'ids': ['1509343309343780875']} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 1011006, 'data': 'yn.luokung.wheel.auth.service.impl.AuthServiceImpl.checkToken(AuthServiceImpl.java:223)', 'message': '请求token错误', 'success': False} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-02 23:59:30,436 C:\work\Study\pytest-auto-api3\logs\info.log:run.py:22 + _ _ _ _____ _ + __ _ _ __ (_) / \ _ _| |_ __|_ _|__ ___| |_ + / _` | '_ \| | / _ \| | | | __/ _ \| |/ _ \/ __| __| + | (_| | |_) | |/ ___ \ |_| | || (_) | | __/\__ \ |_ + \__,_| .__/|_/_/ \_\__,_|\__\___/|_|\___||___/\__| + |_| + 开始执行余少琪的框架项目... + +%(levelname)-8s2022-04-02 23:59:33,188 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 测试patch请求方式 +请求方式: PATCH +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjEyNjU0NzY4OTA2NzI2NzI4MDgsImFjY291bnQiOiJzdXBlckFkbWluIiwidXVpZCI6IjJiOTNlNTNjLWRkM2QtNGM0MS05YjI2LTA1Y2NhM2JjMjNlOSIsInN1YiI6IjEyNjU0NzY4OTA2NzI2NzI4MDgiLCJpYXQiOjE2NDg2ODg2NTgsImV4cCI6MTY0ODc3NTA1OH0.640mDK2Eyid_KjSi0Ijei6VW6LYQZ7oYfGCgq4ajqehACzqfvaG4XJ5lqizRSVhidl7J1XTJZeBYVCjEe0GMdw'} +请求路径: http://39.105.186.77:8082/adpt/advert/adplan/batchDisable +请求内容: {'ids': ['1509343309343780875']} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 1011006, 'data': 'yn.luokung.wheel.auth.service.impl.AuthServiceImpl.checkToken(AuthServiceImpl.java:223)', 'message': '请求token错误', 'success': False} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-03 00:00:24,733 C:\work\Study\pytest-auto-api3\logs\info.log:run.py:22 + _ _ _ _____ _ + __ _ _ __ (_) / \ _ _| |_ __|_ _|__ ___| |_ + / _` | '_ \| | / _ \| | | | __/ _ \| |/ _ \/ __| __| + | (_| | |_) | |/ ___ \ |_| | || (_) | | __/\__ \ |_ + \__,_| .__/|_/_/ \_\__,_|\__\___/|_|\___||___/\__| + |_| + 开始执行余少琪的框架项目... + +%(levelname)-8s2022-04-03 00:00:27,651 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '75322f7df0f59b5643efb6a0a7484067bbb3', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '394de83fa6e06cf968c969bdbb15823a'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-03 00:00:27,658 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532043dc336b9384e0dbba7e0b4b7beaf39', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '2d7e7cc5c1afc1b61fcaae5835dd4bab'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-03 00:00:27,665 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'firstLogin': True, 'token': '7532eebf2c43dcb242bda581ed1394af09d8', 'userBizInfoEntity': {'accountType': 2, 'adSource': '', 'areaName': '', 'baseUserId': 30001, 'bizType': 1, 'cityName': '', 'deleteFlag': False, 'gender': 0, 'gmtCreated': 1598457317000, 'gmtLastActive': 1645752667000, 'gmtModified': 1645752667000, 'marketChannel': '', 'mobile': '13300000000', 'nickname': '余少琪管理员', 'openid': '', 'provinceName': '', 'registerIp': '', 'registrationPlatform': '', 'subBizType': 101, 'unionid': '', 'userIcon': 'https://oss-fg.feng-go.com/assets/pic/grzx_mrtx_pic_user_icon.png', 'userId': 30002, 'userStatus': 0, 'username': '13300000000'}}, 'success': True, 'traceId': '0ba687680c396a902c240f4cdcb617b6'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-03 00:00:28,604 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532eebf2c43dcb242bda581ed1394af09d8'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '440d021f01d18562231fffd73b3645cb'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-03 00:00:28,604 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532eebf2c43dcb242bda581ed1394af09d8'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '7869a398dbd4b1500976b57cb291c20a'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-03 00:00:28,605 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532eebf2c43dcb242bda581ed1394af09d8'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '62fae4f4adee09f05000c04743b52ca5'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-03 00:00:28,720 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532eebf2c43dcb242bda581ed1394af09d8'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'code': 200, 'data': {'data': [{'applyCreateTime': 1637042001000, 'applyId': 105922, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637042001000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'name': '分销商品未设置原价', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3381, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 531, 'thirdCategoryName': '531', 'weight': 10}, {'applyCreateTime': 1637035263000, 'applyId': 105920, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 312, 'brandName': '数据订正2', 'cmsSalesVolume': 0, 'gmtCreate': 1637035263000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/10/085efef1a2b09149bbaedb9cc8954c7d11.jpg', 'marketPrice': 1.0, 'name': '测试商品未设置分销佣金02', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.1, 'shopId': 596, 'shopName': '测试杭州零食铺', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3379, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 100, 'subShopType': 1, 'subShopTypeRemark': 'POP旗舰店', 'supplierId': 274, 'thirdCategoryId': 532, 'thirdCategoryName': '532', 'weight': 10}, {'applyCreateTime': 1633671083000, 'applyId': 105563, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 307, 'brandName': '直播专用品牌', 'cmsSalesVolume': 15, 'gmtCreate': 1633660064000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/07/23ed225b6c90514054bdcd242d8321da01.jpg', 'marketPrice': 1.0, 'name': 'POS支付专用商品', 'originalSalesVolume': 0, 'realSalesVolume': 15, 'sales': 0.3, 'salesVolume': 15, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.02, 'shopId': 515, 'shopName': '余少琪自营店店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 3219, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 84, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 237, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1630915628000, 'applyId': 105316, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 268, 'brandName': '李强商户专营品牌', 'cmsSalesVolume': 10, 'gmtCreate': 1630915628000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/18f9f74bdd-7d04-4ece-a590-cdaae16a4026.jpg', 'marketPrice': 3.0, 'name': '商品测似', 'originalSalesVolume': 10, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 1.0, 'shopId': 291, 'shopName': '李强实体专营店', 'shopSettleMethod': 3, 'shopType': 1, 'shopTypeRemark': 'POP店铺', 'spuBarcode': '', 'spuId': 3140, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 10, 'subShopType': 2, 'subShopTypeRemark': 'POP专营店', 'supplierId': 130, 'thirdCategoryId': 83, 'thirdCategoryName': '83', 'weight': 1}, {'applyCreateTime': 1629698150000, 'applyId': 104903, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698150000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2874, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629698048000, 'applyId': 104902, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629698048000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2873, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695465000, 'applyId': 104900, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695465000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2872, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629695367000, 'applyId': 104899, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629695367000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2871, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690754000, 'applyId': 104898, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690754000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2870, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}, {'applyCreateTime': 1629690576000, 'applyId': 104897, 'applyStatus': 2, 'applyStatusRemark': '待审核', 'brandId': 264, 'brandName': '底价-成本价', 'cmsSalesVolume': 0, 'gmtCreate': 1629690575000, 'icon': 'https://oss-fg.feng-go.com/assets/pic/2021/03/1791e185fd-5ef9-4f7f-b782-57ecfc0ed3d0.jpg', 'marketPrice': 1.0, 'name': '测试商品', 'originalSalesVolume': 0, 'realSalesVolume': 0, 'sales': 0.0, 'salesVolume': 0, 'salesVolumeRule': {'ladder1': 1, 'ladder2': 1, 'ladder3': 1}, 'sellingPrice': 0.5, 'shopId': 287, 'shopName': '李强自营店铺', 'shopSettleMethod': 3, 'shopType': 2, 'shopTypeRemark': '自营店铺', 'spuBarcode': '', 'spuId': 2869, 'spuType': 1, 'status': 1, 'statusRemark': '未上架', 'stockVolume': 2, 'subShopType': 201, 'subShopTypeRemark': '实体自营店', 'supplierId': 130, 'thirdCategoryId': 23, 'thirdCategoryName': '23', 'weight': 10}], 'pageParam': {'applyStatusList': [2, 6], 'applyTypeList': [107, 108, 111], 'bizType': 1, 'limitOffset': 0, 'limitRows': 10, 'page': 1, 'pageNum': 1, 'pageSize': 10, 'refQueryParam1List': ['1', '2', '3', '4'], 'refQueryParam5': '1', 'refType': 5, 'subBizType': 101}, 'totalCount': 47, 'totalPage': 5}, 'success': True, 'traceId': '29105cfb0fe25766532ac15c11008602'} +数据库断言数据: {'sql': None} +================================================================================= +%(levelname)-8s2022-04-03 00:00:28,736 C:\work\Study\pytest-auto-api3\logs\info.log:logDecoratorl.py:37 +================================================================================= +测试标题: 正常审核商品 +请求方式: PUT +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532eebf2c43dcb242bda581ed1394af09d8'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/pass +请求内容: {'applyId': 105922, 'reason': '正常审核商品'} +依赖测试用例: [{'case_id': 'spu_apply_list_01', 'dependent_data': [{'dependent_type': 'response', 'jsonpath': '$.data.data.[0].applyId', 'replace_key': '$.data.applyId'}, {'dependent_type': 'request', 'jsonpath': '$.detail', 'replace_key': '$.data.reason'}]}] +接口响应内容: {'code': 200, 'success': True} +数据库断言数据: {'sql': None} +================================================================================= diff --git a/logs/warning.log.2022-04-03 b/logs/warning.log.2022-04-03 new file mode 100644 index 0000000..9770b74 --- /dev/null +++ b/logs/warning.log.2022-04-03 @@ -0,0 +1,237 @@ +%(levelname)-8s2022-04-02 22:48:54,293 C:\work\Study\pytest-auto-api3\logs\warning.log:assertControl.py:118 该用例当前不执行,跳过断言判断 +%(levelname)-8s2022-04-02 22:56:48,119 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '753263e5f81e3b40436d8b7ceffcdf791c5c'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:57:31,857 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532109233fa72ad486c97e471d6ff2d6204'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: {'res': False} +数据库断言数据: {'sql': False} +================================================================================= +%(levelname)-8s2022-04-02 22:59:47,978 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:00:16,779 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:01:45,748 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:01:45,748 C:\work\Study\pytest-auto-api3\logs\warning.log:conftest.py:61 登录用例设置的是不执行,无法获取到token信息 +%(levelname)-8s2022-04-02 23:01:46,083 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:02:12,204 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:02:12,205 C:\work\Study\pytest-auto-api3\logs\warning.log:conftest.py:61 登录用例设置的是不执行,无法获取到token信息 +%(levelname)-8s2022-04-02 23:02:12,817 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:02:12,840 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:02:12,847 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行.测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:45:41,234 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:45:41,235 C:\work\Study\pytest-auto-api3\logs\warning.log:conftest.py:61 登录用例设置的是不执行,无法获取到token信息 +%(levelname)-8s2022-04-02 23:45:41,626 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:45:41,645 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:45:41,970 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:59:32,711 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:59:32,711 C:\work\Study\pytest-auto-api3\logs\warning.log:conftest.py:61 登录用例设置的是不执行,无法获取到token信息 +%(levelname)-8s2022-04-02 23:59:32,711 C:\work\Study\pytest-auto-api3\logs\warning.log:conftest.py:61 登录用例设置的是不执行,无法获取到token信息 +%(levelname)-8s2022-04-02 23:59:32,714 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 正常登录 +请求方式: POST +请求头: {'Content-Type': 'application/json;charset=UTF-8'} +请求路径: http://work.test.feng-go.com/api/v1/work/user/loginByPassword +请求内容: {'param': {'phone': '13300000000', 'password': '123456'}} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:59:32,715 C:\work\Study\pytest-auto-api3\logs\warning.log:conftest.py:61 登录用例设置的是不执行,无法获取到token信息 +%(levelname)-8s2022-04-02 23:59:33,111 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:59:33,116 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-02 23:59:33,410 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 查看商品审核列表 +请求方式: GET +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'token': '7532b925b258a4c54a7a97e24f668727d0d5'} +请求路径: http://work.test.feng-go.com/api/v1/work/spu/approval/spuList +请求内容: {'spuType': 1, 'pageNum': 1, 'pageSize': 10} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= +%(levelname)-8s2022-04-03 00:00:28,088 C:\work\Study\pytest-auto-api3\logs\warning.log:logDecoratorl.py:51 +================================================================================= +该条用例跳过执行. +测试标题: 测试patch请求方式 +请求方式: PATCH +请求头: {'Content-Type': 'application/json;charset=UTF-8', 'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjEyNjU0NzY4OTA2NzI2NzI4MDgsImFjY291bnQiOiJzdXBlckFkbWluIiwidXVpZCI6IjJiOTNlNTNjLWRkM2QtNGM0MS05YjI2LTA1Y2NhM2JjMjNlOSIsInN1YiI6IjEyNjU0NzY4OTA2NzI2NzI4MDgiLCJpYXQiOjE2NDg2ODg2NTgsImV4cCI6MTY0ODc3NTA1OH0.640mDK2Eyid_KjSi0Ijei6VW6LYQZ7oYfGCgq4ajqehACzqfvaG4XJ5lqizRSVhidl7J1XTJZeBYVCjEe0GMdw'} +请求路径: http://39.105.186.77:8082/adpt/advert/adplan/batchDisable +请求内容: {'ids': ['1509343309343780875']} +依赖测试用例: 暂无依赖用例数据 +接口响应内容: False +数据库断言数据: False +================================================================================= diff --git a/pytest.ini b/pytest.ini index 2b0c9ef..9d56ab9 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,4 +1,9 @@ [pytest] +addopts = -p no:warnings +testpaths = test_case/ +python_files = test_*.py +python_classes = Test* +python_function = test_* + markers = - shop: project_shop - shop_list: project_shop_list + smoke: 冒烟测试 diff --git a/report/tmp/environment.xml b/report/tmp/environment.xml deleted file mode 100644 index 646dba1..0000000 --- a/report/tmp/environment.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - 测试平台 - 测试项目 - - - 测试环境 - TEST - - - 测试人员 - 余少琪 - - - 邮箱 - 1603453211@qq.com - - - python.Version - 3.9.0 - - \ No newline at end of file diff --git a/run.py b/run.py index 9dced57..94bc098 100644 --- a/run.py +++ b/run.py @@ -1,23 +1,23 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/26 23:12 +# @Time : 2022/3/29 15:01 # @Author : 余少琪 -import traceback -import pytest import os -from tools.logControl import INFO -from tools.yamlControl import GetYamlData -from config.setting import ConfigHandler -from tools import getNotificationType -from tools.weChatSendControl import WeChatSend -from tools.dingtalkControl import DingTalkSendMsg -from tools.sendmailControl import SendEmail +import traceback +import pytest +from utils import project_name +from utils.logUtils.logControl import INFO +from utils import get_notification_type +from utils.noticUtils.weChatSendControl import WeChatSend +from utils.noticUtils.dingtalkControl import DingTalkSendMsg +from utils.noticUtils.sendmailControl import SendEmail +from Enums.notificationType_enum import NotificationType +from utils.noticUtils.feishuControl import FeiShuTalkChatBot def run(): # 从配置文件中获取项目名称 - project_name = GetYamlData(ConfigHandler.config_path).get_yaml_data()['ProjectName'][0] try: INFO.logger.info( """ @@ -30,15 +30,33 @@ def run(): 开始执行{}项目... """.format(project_name) ) - pytest.main(['-s', '-W', 'ignore:Module already imported:pytest.PytestWarning', '--alluredir', './report/tmp']) + + pytest.main(['-s', '-W', 'ignore:Module already imported:pytest.PytestWarning', + '--alluredir', './report/tmp']) + """ + --reruns: 失败重跑次数 + --count: 重复执行次数 + -v: 显示错误位置以及错误的详细信息 + -s: 等价于 pytest --capture=no 可以捕获print函数的输出 + -q: 简化输出信息 + -m: 运行指定标签的测试用例 + -x: 一旦错误,则停止运行 + --maxfail: 设置最大失败次数,当超出这个阈值时,则不会在执行测试用例 + "--reruns=3", "--reruns-delay=2" + """ + os.system(r"allure generate ./report/tmp -o ./report/html --clean") - # 通过配置文件判断发送报告通知类型:1:钉钉 2:企业微信通知 3、邮箱 - if getNotificationType() == 1: + # 判断通知类型 + if get_notification_type() == NotificationType.DEFAULT.value: + pass + elif get_notification_type() == NotificationType.DING_TALK.value: DingTalkSendMsg().send_ding_notification() - elif getNotificationType() == 2: - WeChatSend().send_email_notification() - elif getNotificationType() == 3: + elif get_notification_type() == NotificationType.WECHAT.value: + WeChatSend().send_wechat_notification() + elif get_notification_type() == NotificationType.EMAIL.value: SendEmail().send_main() + elif get_notification_type() == NotificationType.FEI_SHU.value: + FeiShuTalkChatBot().post() else: raise ValueError("通知类型配置错误,暂不支持该类型通知") os.system(f"allure serve ./report/tmp -p 9999") diff --git a/test_case/Login/__pycache__/test_login.cpython-39-pytest-7.1.1.pyc b/test_case/Login/__pycache__/test_login.cpython-39-pytest-7.1.1.pyc new file mode 100644 index 0000000..67a1d7d Binary files /dev/null and b/test_case/Login/__pycache__/test_login.cpython-39-pytest-7.1.1.pyc differ diff --git a/test_case/Login/test_login.py b/test_case/Login/test_login.py new file mode 100644 index 0000000..b45a9af --- /dev/null +++ b/test_case/Login/test_login.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022-04-07 21:03:43 +# @Author : 余少琪 + + +import allure +import pytest +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.assertUtils.assertControl import Assert +from utils.requestsUtils.requestControl import RequestControl + + +TestData = CaseData(ConfigHandler.data_path + r'Login/login.yaml').case_process() + + +@allure.epic("电商平台端") +@allure.feature("登录模块") +class TestLogin: + + @allure.story("正常登录") + @pytest.mark.parametrize('in_data', TestData, ids=[i['detail'] for i in TestData]) + def test_login(self, in_data, case_skip): + """ + :param : + :return: + """ + + res = RequestControl().http_request(in_data) + Assert(in_data['assert']).assert_equality(response_data=res[0], sql_data=res[1]) + + +if __name__ == '__main__': + pytest.main(['test_login.py', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning']) diff --git a/test_case/TestMerchant/TestLogin/__pycache__/test_case_demo.cpython-38-pytest-6.2.3.pyc b/test_case/TestMerchant/TestLogin/__pycache__/test_case_demo.cpython-38-pytest-6.2.3.pyc deleted file mode 100644 index 8760697..0000000 Binary files a/test_case/TestMerchant/TestLogin/__pycache__/test_case_demo.cpython-38-pytest-6.2.3.pyc and /dev/null differ diff --git a/test_case/TestMerchant/TestLogin/__pycache__/test_case_demo.cpython-38-pytest-6.2.5.pyc b/test_case/TestMerchant/TestLogin/__pycache__/test_case_demo.cpython-38-pytest-6.2.5.pyc deleted file mode 100644 index bc2bbc9..0000000 Binary files a/test_case/TestMerchant/TestLogin/__pycache__/test_case_demo.cpython-38-pytest-6.2.5.pyc and /dev/null differ diff --git a/test_case/WorkApplyCenter/__pycache__/test_spu_apply.cpython-39-pytest-7.1.1.pyc b/test_case/WorkApplyCenter/__pycache__/test_spu_apply.cpython-39-pytest-7.1.1.pyc new file mode 100644 index 0000000..2740a5d Binary files /dev/null and b/test_case/WorkApplyCenter/__pycache__/test_spu_apply.cpython-39-pytest-7.1.1.pyc differ diff --git a/test_case/WorkApplyCenter/__pycache__/test_sup_apply_list.cpython-39-pytest-7.1.1.pyc b/test_case/WorkApplyCenter/__pycache__/test_sup_apply_list.cpython-39-pytest-7.1.1.pyc new file mode 100644 index 0000000..7938cd1 Binary files /dev/null and b/test_case/WorkApplyCenter/__pycache__/test_sup_apply_list.cpython-39-pytest-7.1.1.pyc differ diff --git a/test_case/WorkApplyCenter/__pycache__/test_work_apply_good_detail.cpython-39-pytest-7.1.1.pyc b/test_case/WorkApplyCenter/__pycache__/test_work_apply_good_detail.cpython-39-pytest-7.1.1.pyc new file mode 100644 index 0000000..c6df0df Binary files /dev/null and b/test_case/WorkApplyCenter/__pycache__/test_work_apply_good_detail.cpython-39-pytest-7.1.1.pyc differ diff --git a/test_case/WorkApplyCenter/test_batchDisable.py b/test_case/WorkApplyCenter/test_batchDisable.py new file mode 100644 index 0000000..7de4762 --- /dev/null +++ b/test_case/WorkApplyCenter/test_batchDisable.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022-04-07 21:03:43 +# @Author : 余少琪 + + +import allure +import pytest +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.assertUtils.assertControl import Assert +from utils.requestsUtils.requestControl import RequestControl + + +TestData = CaseData(ConfigHandler.data_path + r'uplpad_file_test/batchDisable.yaml').case_process() + + +@allure.epic("换社会") +@allure.feature("登录模块") +class TestBatchdisable: + + @allure.story("测试patch请求方式") + @pytest.mark.parametrize('in_data', TestData, ids=[i['detail'] for i in TestData]) + def test_batchDisable(self, in_data, case_skip): + """ + :param : + :return: + """ + + res = RequestControl().http_request(in_data) + Assert(in_data['assert']).assert_equality(response_data=res[0], sql_data=res[1]) + + +if __name__ == '__main__': + pytest.main(['test_batchDisable.py', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning']) diff --git a/test_case/WorkApplyCenter/test_spu_apply.py b/test_case/WorkApplyCenter/test_spu_apply.py new file mode 100644 index 0000000..23297da --- /dev/null +++ b/test_case/WorkApplyCenter/test_spu_apply.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022-04-07 21:03:43 +# @Author : 余少琪 + + +import allure +import pytest +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.assertUtils.assertControl import Assert +from utils.requestsUtils.requestControl import RequestControl + + +TestData = CaseData(ConfigHandler.data_path + r'WorkApplyCenter/spu_apply.yaml').case_process() + + +@allure.epic("电商平台端") +@allure.feature("审核中心") +class TestSpuApply: + + @allure.story("商品审核") + @pytest.mark.parametrize('in_data', TestData, ids=[i['detail'] for i in TestData]) + def test_spu_apply(self, in_data, case_skip): + """ + :param : + :return: + """ + + res = RequestControl().http_request(in_data) + Assert(in_data['assert']).assert_equality(response_data=res[0], sql_data=res[1]) + + +if __name__ == '__main__': + pytest.main(['test_spu_apply.py', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning']) diff --git a/test_case/WorkApplyCenter/test_sup_apply_list.py b/test_case/WorkApplyCenter/test_sup_apply_list.py new file mode 100644 index 0000000..782bd94 --- /dev/null +++ b/test_case/WorkApplyCenter/test_sup_apply_list.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022-04-07 21:03:43 +# @Author : 余少琪 + + +import allure +import pytest +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.assertUtils.assertControl import Assert +from utils.requestsUtils.requestControl import RequestControl + + +TestData = CaseData(ConfigHandler.data_path + r'WorkApplyCenter/sup_apply_list.yaml').case_process() + + +@allure.epic("电商平台端") +@allure.feature("审核中心") +class TestSupApplyList: + + @allure.story("商品审核列表") + @pytest.mark.parametrize('in_data', TestData, ids=[i['detail'] for i in TestData]) + def test_sup_apply_list(self, in_data, case_skip): + """ + :param : + :return: + """ + + res = RequestControl().http_request(in_data) + Assert(in_data['assert']).assert_equality(response_data=res[0], sql_data=res[1]) + + +if __name__ == '__main__': + pytest.main(['test_sup_apply_list.py', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning']) diff --git a/test_case/WorkApplyCenter/test_work_apply_good_detail.py b/test_case/WorkApplyCenter/test_work_apply_good_detail.py new file mode 100644 index 0000000..4e7c53d --- /dev/null +++ b/test_case/WorkApplyCenter/test_work_apply_good_detail.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022-04-07 21:03:43 +# @Author : 余少琪 + + +import allure +import pytest +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.assertUtils.assertControl import Assert +from utils.requestsUtils.requestControl import RequestControl + + +TestData = CaseData(ConfigHandler.data_path + r'WorkApplyCenter/work_apply_good_detail.yaml').case_process() + + +@allure.epic("电商平台端") +@allure.feature("审核中心") +class TestWorkApplyGoodDetail: + + @allure.story("商品审核详情") + @pytest.mark.parametrize('in_data', TestData, ids=[i['detail'] for i in TestData]) + def test_work_apply_good_detail(self, in_data, case_skip): + """ + :param : + :return: + """ + + res = RequestControl().http_request(in_data) + Assert(in_data['assert']).assert_equality(response_data=res[0], sql_data=res[1]) + + +if __name__ == '__main__': + pytest.main(['test_work_apply_good_detail.py', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning']) diff --git a/test_case/__pycache__/__init__.cpython-38.pyc b/test_case/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 0dc84ec..0000000 Binary files a/test_case/__pycache__/__init__.cpython-38.pyc and /dev/null differ diff --git a/test_case/__pycache__/conftest.cpython-38-pytest-6.2.3.pyc b/test_case/__pycache__/conftest.cpython-38-pytest-6.2.3.pyc deleted file mode 100644 index bb40ee2..0000000 Binary files a/test_case/__pycache__/conftest.cpython-38-pytest-6.2.3.pyc and /dev/null differ diff --git a/test_case/__pycache__/conftest.cpython-38-pytest-6.2.5.pyc b/test_case/__pycache__/conftest.cpython-38-pytest-6.2.5.pyc deleted file mode 100644 index f62588c..0000000 Binary files a/test_case/__pycache__/conftest.cpython-38-pytest-6.2.5.pyc and /dev/null differ diff --git a/test_case/__pycache__/conftest.cpython-39-pytest-7.1.1.pyc b/test_case/__pycache__/conftest.cpython-39-pytest-7.1.1.pyc new file mode 100644 index 0000000..bcf2ff3 Binary files /dev/null and b/test_case/__pycache__/conftest.cpython-39-pytest-7.1.1.pyc differ diff --git a/test_case/conftest.py b/test_case/conftest.py index 4701b7e..abd10a8 100644 --- a/test_case/conftest.py +++ b/test_case/conftest.py @@ -1,21 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/28 23:05 +# @Time : 2022/3/30 14:12 # @Author : 余少琪 -import pytest + import os +import pytest +import time +import allure +from utils.requestsUtils.requestControl import RequestControl from config.setting import ConfigHandler -from tools.yamlControl import GetYamlData - - -_PROJECT_NAME = GetYamlData(ConfigHandler.config_path).get_yaml_data()['ProjectName'][0] -_TEST_NAME = GetYamlData(ConfigHandler.config_path).get_yaml_data()['TestName'] +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.cacheUtils.cacheControl import Cache +from utils.readFilesUtils.get_all_files_path import get_all_files +from utils.logUtils.logControl import WARNING, INFO, ERROR +from Enums.yamlData_enum import YAMLDate +from utils.otherUtils.allureDate.allure_tools import allure_step, allure_step_no @pytest.fixture(scope="session", autouse=True) def clear_report(): try: - for one in os.listdir(ConfigHandler.report_path + f'/tmp'): + for one in os.listdir(ConfigHandler.report_path + '/tmp'): if 'json' in one: os.remove(ConfigHandler.report_path + f'/tmp/{one}') if 'txt' in one: @@ -26,3 +31,101 @@ def clear_report(): yield +@pytest.fixture(scope="session", autouse=True) +def write_case_process(): + """ + 获取所有用例,写入用例池中 + :return: + """ + case_data = {} + # 循环拿到所有存放用例的文件路径 + for i in get_all_files(ConfigHandler.data_path): + # 循环读取文件中的数据 + case_process = CaseData(i).case_process(case_id_switch=True) + # 转换数据类型 + for case in case_process: + for k, v in case.items(): + # 判断 case_id 是否已存在 + case_id_exit = k in case_data.keys() + # 如果case_id 不存在,则将用例写入缓存池中 + if case_id_exit is False: + case_data[k] = v + # 当 case_id 为 True 存在时,则跑出异常 + elif case_id_exit is True: + raise ValueError(f"case_id: {k} 存在重复项, 请修改case_id\n" + f"文件路径: {i}") + + Cache('case_process').set_caches(case_data) + + +@pytest.fixture(scope="session", autouse=True) +def work_login_init(): + """ + 获取平台端的token信息 + :return: + """ + login_yaml = CaseData(ConfigHandler.data_path + 'Login/login.yaml').case_process()[0] + res = RequestControl().http_request(login_yaml) + # 将token写入缓存中 + if res[0] is not False: + token = res[0]['data']['token'] + Cache('work_login_init').set_caches(token) + return token + else: + WARNING.logger.warning("登录用例设置的是不执行,无法获取到token信息") + + +def pytest_collection_modifyitems(items): + """ + 测试用例收集完成时,将收集到的 item 的 name 和 node_id 的中文显示在控制台上 + :return: + """ + for item in items: + item.name = item.name.encode("utf-8").decode("unicode_escape") + item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape") + + +# 定义单个标签 +def pytest_configure(config): + config.addinivalue_line( + "markers", "smoke" + ) + + +@pytest.fixture(scope="function", autouse=True) +def case_skip(in_data): + """处理跳过用例""" + if in_data['is_run'] is False: + allure.dynamic.title(in_data[YAMLDate.DETAIL.value]) + allure_step_no(f"请求URL: {in_data[YAMLDate.IS_RUN.value]}") + allure_step_no(f"请求方式: {in_data[YAMLDate.METHOD.value]}") + allure_step("请求头: ", in_data[YAMLDate.HEADER.value]) + allure_step("请求数据: ", in_data[YAMLDate.DATA.value]) + allure_step("依赖数据: ", in_data[YAMLDate.DEPENDENCE_CASE_DATA.value]) + allure_step("预期数据: ", in_data[YAMLDate.ASSERT.value]) + pytest.skip() + + +def pytest_terminal_summary(terminalreporter): + """ + 收集测试结果 + """ + + _PASSED = len([i for i in terminalreporter.stats.get('passed', []) if i.when != 'teardown']) + _ERROR = len([i for i in terminalreporter.stats.get('error', []) if i.when != 'teardown']) + _FAILED = len([i for i in terminalreporter.stats.get('failed', []) if i.when != 'teardown']) + _SKIPPED = len([i for i in terminalreporter.stats.get('skipped', []) if i.when != 'teardown']) + _TOTAL = terminalreporter._numcollected + _TIMES = time.time() - terminalreporter._sessionstarttime + + INFO.logger.info(f"成功用例数: {_PASSED}") + ERROR.logger.error(f"异常用例数: {_ERROR}") + ERROR.logger.error(f"失败用例数: {_FAILED}") + WARNING.logger.warning(f"跳过用例数: {_SKIPPED}") + INFO.logger.info("用例执行时长: %.2f" % _TIMES + " s") + + try: + _RATE = round((_PASSED + _SKIPPED) / _TOTAL * 100, 2) + INFO.logger.info("用例成功率: %.2f" % _RATE + " %") + except ZeroDivisionError: + INFO.logger.info("用例成功率: 0.00 %") diff --git a/test_case/test_demo/test_DateDemo.py b/test_case/test_demo/test_DateDemo.py deleted file mode 100644 index 602ae59..0000000 --- a/test_case/test_demo/test_DateDemo.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2022-03-16 13:07:13 -# @Author : 余少琪 - - -import allure -import pytest -from config.setting import ConfigHandler -from tools.yamlControl import GetCaseData -from lib.test_demo.DateDemo import DateDemo -from tools.assertControl import Assert - -TestData = GetCaseData(ConfigHandler.merchant_data_path + r'test_demo\DateDemo.yaml').get_yaml_case_data() - - -@allure.epic("这里是测试平台名称") -@allure.feature("这里是测试模块名称") -class TestDateDemo: - - @allure.story("这是一个测试的demo接口") - @pytest.mark.parametrize('data', TestData) - def test_date_demo(self, date): - """ - 测试接口 - :param : - :return: - """ - - res = DateDemo().dateDemo(date) - Assert(date['resp']).assert_equality(response_data=res[0], sql_data=res[1]) - - -if __name__ == '__main__': - pytest.main(['test_DateDemo.py', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning', "--reruns=2", - "--reruns-delay=2"]) diff --git a/test_case/uplpad_file_test/__pycache__/test_batchDisable.cpython-39-pytest-7.1.1.pyc b/test_case/uplpad_file_test/__pycache__/test_batchDisable.cpython-39-pytest-7.1.1.pyc new file mode 100644 index 0000000..543f3f2 Binary files /dev/null and b/test_case/uplpad_file_test/__pycache__/test_batchDisable.cpython-39-pytest-7.1.1.pyc differ diff --git a/test_case/uplpad_file_test/__pycache__/test_up_files.cpython-39-pytest-7.1.1.pyc b/test_case/uplpad_file_test/__pycache__/test_up_files.cpython-39-pytest-7.1.1.pyc new file mode 100644 index 0000000..b21972d Binary files /dev/null and b/test_case/uplpad_file_test/__pycache__/test_up_files.cpython-39-pytest-7.1.1.pyc differ diff --git a/test_case/uplpad_file_test/__pycache__/test_upload_files.cpython-39-pytest-7.1.1.pyc b/test_case/uplpad_file_test/__pycache__/test_upload_files.cpython-39-pytest-7.1.1.pyc new file mode 100644 index 0000000..8c5e0e5 Binary files /dev/null and b/test_case/uplpad_file_test/__pycache__/test_upload_files.cpython-39-pytest-7.1.1.pyc differ diff --git a/test_case/uplpad_file_test/test_up_files.py b/test_case/uplpad_file_test/test_up_files.py new file mode 100644 index 0000000..3e559a3 --- /dev/null +++ b/test_case/uplpad_file_test/test_up_files.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022-04-07 21:03:43 +# @Author : 余少琪 + + +import allure +import pytest +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.assertUtils.assertControl import Assert +from utils.requestsUtils.requestControl import RequestControl + + +TestData = CaseData(ConfigHandler.data_path + r'uplpad_file_test/up_files.yaml').case_process() + + +@allure.epic("婚奢汇") +@allure.feature("文件上传") +class TestUpFiles: + + @allure.story("上传excel文件") + @pytest.mark.parametrize('in_data', TestData, ids=[i['detail'] for i in TestData]) + def test_up_files(self, in_data, case_skip): + """ + :param : + :return: + """ + + res = RequestControl().http_request(in_data) + Assert(in_data['assert']).assert_equality(response_data=res[0], sql_data=res[1]) + + +if __name__ == '__main__': + pytest.main(['test_up_files.py', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning']) diff --git a/test_case/uplpad_file_test/test_upload_files.py b/test_case/uplpad_file_test/test_upload_files.py new file mode 100644 index 0000000..82b695f --- /dev/null +++ b/test_case/uplpad_file_test/test_upload_files.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022-04-07 21:03:43 +# @Author : 余少琪 + + +import allure +import pytest +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.assertUtils.assertControl import Assert +from utils.requestsUtils.requestControl import RequestControl + + +TestData = CaseData(ConfigHandler.data_path + r'uplpad_file_test/upload_files.yaml').case_process() + + +@allure.epic("婚奢汇") +@allure.feature("文件上传") +class TestUploadFiles: + + @allure.story("上传excel文件") + @pytest.mark.parametrize('in_data', TestData, ids=[i['detail'] for i in TestData]) + def test_upload_files(self, in_data, case_skip): + """ + :param : + :return: + """ + + res = RequestControl().http_request(in_data) + Assert(in_data['assert']).assert_equality(response_data=res[0], sql_data=res[1]) + + +if __name__ == '__main__': + pytest.main(['test_upload_files.py', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning']) diff --git a/tools/__init__.py b/tools/__init__.py deleted file mode 100644 index 0190aac..0000000 --- a/tools/__init__.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2021/12/14 22:06 -# @Author : 余少琪 - -import allure -import json -import datetime -from config.setting import get_current_system, ConfigHandler -from tools.yamlControl import GetYamlData - - -def allure_step(step: str, var: str) -> None: - """ - :param step: 步骤及附件名称 - :param var: 附件内容 - """ - with allure.step(step): - allure.attach( - json.dumps( - str(var), - ensure_ascii=False, - indent=4), - step, - allure.attachment_type.JSON) - - -def allure_step_no(step: str): - """ - 无附件的操作步骤 - :param step: 步骤名称 - :return: - """ - with allure.step(step): - pass - - -def slash(): - # 判断系统路径 - SLASH = '\\' - - # 判断当前操作系统 - if get_current_system() == 'Linux' or get_current_system() == "Darwin": - SLASH = '/' - - return SLASH - - -def SqlSwitch() -> bool: - """获取数据库开关""" - switch = GetYamlData(ConfigHandler.config_path) \ - .get_yaml_data()['MySqlDB']["switch"] - return switch - - -def getNotificationType(): - # 获取报告通知类型,是发送钉钉还是企业邮箱 - Date = GetYamlData(ConfigHandler.config_path).get_yaml_data()['NotificationType'] - return Date - - -def writePageFiles(classTitle, funcTitle, caseDetail, casePath, yamlPath): - """ - 自动写成 py 文件 - :param yamlPath: - :param casePath: 生成的py文件地址 - :param classTitle: 类名称, 读取用例中的 caseTitle 作为类名称 - :param funcTitle: 函数名称 caseTitle,首字母小写 - :param caseDetail: 函数描述,读取用例中的描述内容,做为函数描述 - :return: - """ - Author = GetYamlData(ConfigHandler.config_path).get_yaml_data()['TestName'] - now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - - page = f'''#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : {now} -# @Author : {Author} - - -from tools.requestControl import RequestControl -from tools.yamlControl import GetCaseData -from config.setting import ConfigHandler - - -class {classTitle}(object): - @staticmethod - def {funcTitle}(inData): - """ - {caseDetail} - :param inData: - :return: - """ - - resp = RequestControl().HttpRequest(inData['method'], inData) - return resp - - -if __name__ == '__main__': - path = GetCaseData(ConfigHandler.data_path + r'{yamlPath}').get_yaml_case_data()[0] - data = {classTitle}().{funcTitle}(path) - print(data) - ''' - with open(casePath, 'w', encoding="utf-8") as f: - f.write(page) - - -def writeTestCaseFile(allureEpic, allureFeature, classTitle, funcTitle, caseDetail, casePath, yamlPath, fileName, PackagePath): - """ - - :param allureEpic: 项目名称 - :param allureFeature: 模块名称 - :param classTitle: 类名称 - :param funcTitle: 函数名称 - :param caseDetail: 用例描述 - :param casePath: case 路径 - :param yamlPath: yaml 文件路径 - :return: - """ - Author = GetYamlData(ConfigHandler.config_path).get_yaml_data()['TestName'] - now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - page = f'''#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : {now} -# @Author : {Author} - - -import allure -import pytest -from config.setting import ConfigHandler -from tools.yamlControl import GetCaseData -{PackagePath} -from tools.assertControl import Assert - -TestData = GetCaseData(ConfigHandler.merchant_data_path + r'{yamlPath}').get_yaml_case_data() - - -@allure.epic("{allureEpic}") -@allure.feature("{allureFeature}") -class Test{classTitle}: - - @allure.story("这是一个测试的demo接口") - @pytest.mark.parametrize('inData', TestData) - def test_{funcTitle}(self, inData): - """ - {caseDetail} - :param : - :return: - """ - - res = {classTitle}().{funcTitle}(inData) - Assert(inData['resp']).assertEquality(responseData=res[0], sqlData=res[1]) - - -if __name__ == '__main__': - pytest.main(['{fileName}', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning', "--reruns=2", "--reruns-delay=2"]) -''' - with open(casePath, 'w', encoding="utf-8") as f: - f.write(page) diff --git a/tools/__pycache__/__init__.cpython-38.pyc b/tools/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 69c2a62..0000000 Binary files a/tools/__pycache__/__init__.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/assertControl.cpython-38.pyc b/tools/__pycache__/assertControl.cpython-38.pyc deleted file mode 100644 index 72068b1..0000000 Binary files a/tools/__pycache__/assertControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/dingtalkControl.cpython-38.pyc b/tools/__pycache__/dingtalkControl.cpython-38.pyc deleted file mode 100644 index 1e5e829..0000000 Binary files a/tools/__pycache__/dingtalkControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/gettimeControl.cpython-38.pyc b/tools/__pycache__/gettimeControl.cpython-38.pyc deleted file mode 100644 index e9f6c73..0000000 Binary files a/tools/__pycache__/gettimeControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/localIpControl.cpython-38.pyc b/tools/__pycache__/localIpControl.cpython-38.pyc deleted file mode 100644 index d1e25cb..0000000 Binary files a/tools/__pycache__/localIpControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/logDecorator.cpython-38.pyc b/tools/__pycache__/logDecorator.cpython-38.pyc deleted file mode 100644 index 3bee7e5..0000000 Binary files a/tools/__pycache__/logDecorator.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/mysqlControl.cpython-38.pyc b/tools/__pycache__/mysqlControl.cpython-38.pyc deleted file mode 100644 index a8a1a2d..0000000 Binary files a/tools/__pycache__/mysqlControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/regularControl.cpython-38.pyc b/tools/__pycache__/regularControl.cpython-38.pyc deleted file mode 100644 index 7ecc05a..0000000 Binary files a/tools/__pycache__/regularControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/requestControl.cpython-38.pyc b/tools/__pycache__/requestControl.cpython-38.pyc deleted file mode 100644 index 36d8797..0000000 Binary files a/tools/__pycache__/requestControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/runtimeControl.cpython-38.pyc b/tools/__pycache__/runtimeControl.cpython-38.pyc deleted file mode 100644 index b137fc1..0000000 Binary files a/tools/__pycache__/runtimeControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/sendmailControl.cpython-38.pyc b/tools/__pycache__/sendmailControl.cpython-38.pyc deleted file mode 100644 index 3b2b47a..0000000 Binary files a/tools/__pycache__/sendmailControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/weChatSendControl.cpython-38.pyc b/tools/__pycache__/weChatSendControl.cpython-38.pyc deleted file mode 100644 index 4f77fe7..0000000 Binary files a/tools/__pycache__/weChatSendControl.cpython-38.pyc and /dev/null differ diff --git a/tools/__pycache__/yamlControl.cpython-38.pyc b/tools/__pycache__/yamlControl.cpython-38.pyc deleted file mode 100644 index 5f9e492..0000000 Binary files a/tools/__pycache__/yamlControl.cpython-38.pyc and /dev/null differ diff --git a/tools/assertControl.py b/tools/assertControl.py deleted file mode 100644 index 2ea6205..0000000 --- a/tools/assertControl.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2021/11/26 21:03 -# @Author : 余少琪 -from tools.yamlControl import GetCaseData -from config.setting import ConfigHandler -import jsonpath -from tools.logControl import ERROR, WARNING -from tools import SqlSwitch - - -class Transmission: - EQUAL: str = "==" - NOTEQUAL: str = "!=" - IN: str = "IN" - NOTIN: str = "NOTIN" - - -class Assert: - - def __init__(self, assert_date: dict): - self.GetCaseData = GetCaseData(ConfigHandler.merchant_data_path + r'\ShopInfo\GetSupplierInfo.yaml') - self.assertData = assert_date - - @staticmethod - def _check_params(response_data: dict, sql_data: dict): - """ - - :param response_data: 响应数据 - :param sql_data: 数据库数据 - :return: - """ - # 判断断言的数据类型 - if isinstance(response_data, dict) and isinstance(sql_data, dict): - pass - else: - raise ValueError("responseData、sqlData、assertData的数据类型必须要是字典类型") - - @staticmethod - def _assert_type(key: any, assert_type: str, value: any): - """ - - :param key: - :param assert_type: - :param value: - :return: - """ - try: - if assert_type == Transmission.EQUAL: - assert key == value - elif assert_type == Transmission.NOTEQUAL: - assert key != value - elif assert_type.upper() == Transmission.IN: - assert key in value - elif assert_type.upper() == Transmission.NOTIN: - assert key not in value - - else: - raise ValueError(f"断言失败,目前不支持{assert_type}断言类型,如需新增断言类型,请联系管理员") - # 断言成功的日志,需要的话可以自动开启 - # INFO.logger.info("断言成功, 预期值:{}, 断言类型{}, 实际值{}".format(value, Type, key)) - - except AssertionError: - ERROR.logger.error("断言失败, 预期值:{}, 断言类型{}, 实际值{}".format(value, assert_type, key)) - raise - - def sql_switch_handle(self, sql_date, assert_value, key, values, resp_data) -> None: - """ - - :param sql_date: 测试用例中的sql - :param assert_value: 断言内容 - :param key: - :param values: - :param resp_data: 预期结果 - :return: - """ - # 判断数据库为开关为关闭状态 - if SqlSwitch() is False: - WARNING.logger.warning(f"检测到数据库状态为关闭状态,程序已为您跳过此断言,断言值:{values}") - # 数据库开关为开启 - if SqlSwitch(): - # 判断当用例走的数据数据库断言,但是用例中未填写SQL - if sql_date == {'sql': None}: - raise ValueError("请在用例中添加您要查询的SQL语句。") - # 走正常SQL断言逻辑 - else: - res_sql_data = jsonpath.jsonpath(sql_date, assert_value)[0] - # 判断mysql查询出来的数据类型如果是bytes类型,转换成str类型 - if isinstance(res_sql_data, bytes): - res_sql_data = res_sql_data.decode('utf=8') - self._assert_type(assert_type=self.assertData[key]['type'], key=resp_data[0], value=res_sql_data) - - def assert_type_handle(self, assert_type, sql_data, assert_value, key, values, resp_data) -> None: - # 判断断言类型 - if assert_type == 'SQL': - self.sql_switch_handle(sql_data, assert_value, key, values, resp_data) - # 判断assertType为空的情况下,则走响应断言 - elif assert_type is None: - self._assert_type(assert_type=self.assertData[key]['type'], key=resp_data[0], value=resp_data) - else: - raise ValueError("断言失败,目前只支持数据库断言和响应断言") - - def assert_equality(self, response_data: dict, sql_data: dict) -> None: - # 判断数据类型 - self._check_params(response_data, sql_data) - for key, values in self.assertData.items(): - assert_value = self.assertData[key]['value'] # 获取 yaml 文件中的期望value值 - assert_json_path = self.assertData[key]['jsonpath'] # 获取到 yaml断言中的jsonpath的数据 - assert_type = self.assertData[key]['AssertType'] - # 从yaml获取jsonpath,拿到对象的接口响应数据 - resp_data = jsonpath.jsonpath(response_data, assert_json_path) - - # jsonpath 如果数据获取失败,会返回False,判断获取成功才会执行如下代码 - if resp_data is not False: - # 判断断言类型 - self.assert_type_handle(assert_type, sql_data, assert_value, key, values, resp_data) - else: - ERROR.logger.error("JsonPath值获取失败{}".format(assert_json_path)) - raise diff --git a/tools/logDecorator.py b/tools/logDecorator.py deleted file mode 100644 index 4d3a87c..0000000 --- a/tools/logDecorator.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2021/11/30 23:25 -# @Author : 余少琪 -from functools import wraps -from tools.logControl import INFO - - -def log_decorator(switch: bool): - """ - 封装日志装饰器, 打印请求信息 - :param switch: 定义日志开关 - :return: - """ - # 判断参数类型是否是 int 类型 - if isinstance(switch, bool): - def decorator(func): - @wraps(func) - def swapper(*args, **kwargs): - # 判断日志为开启状态,才打印日志 - res = func(*args, **kwargs) - if switch: - if res is not None: - INFO.logger.info( - f"\n=================================================================================\n" - f"测试标题: {res[2]['detail']}\n" - f"请求方式: {res[2]['method']}\n" - f"请求头: {res[2]['headers']}\n" - f"请求路径: {res[2]['url']}\n" - f"请求内容: {res[2]['data']}\n" - f"接口响应内容: {res[0]}\n" - f"数据库断言数据: {res[1]}\n" - "=================================================================================" - - ) - return res - else: - return res - return swapper - - return decorator - else: - raise TypeError("日志开关只能为 Ture 或者 False") \ No newline at end of file diff --git a/tools/requestControl.py b/tools/requestControl.py deleted file mode 100644 index 0abb89b..0000000 --- a/tools/requestControl.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2021/11/24 23:28 -# @Author : 余少琪 - -import requests -from tools.logControl import ERROR -from tools.runtimeControl import execution_duration -from tools.mysqlControl import MysqlDB -import allure -from tools.logDecorator import log_decorator -from tools import allure_step, allure_step_no, SqlSwitch - - -class Transmission: - JSON: str = "json" - PARAMS: str = "params" - DATE: str = "date" - FILE: str = 'file' - - -class RequestControl: - """ 封装请求 """ - - def __init__(self): - # TODO 初始化逻辑调整 - pass - - @classmethod - def _check_params(cls, res, data: dict) -> tuple: - """ 抽离出通用模块,判断request中的一些参数校验 """ - if 'url' and 'data' and 'headers' and 'sql' not in data: - ERROR.logger.error("请求失败,请检查用例数据中是否缺少必要参数[url, data, headers, sql]") - else: - # 判断响应码不等于200时,打印文本格式信息 - if res.status_code != 200: - return res.text, {"sql": None}, data - # 判断数据库开关为开启状态,获取数据库的数据,并且返回 - if SqlSwitch() and data['sql'] is not None: - sql_data = MysqlDB().assert_execution(data['sql'], res.json()) - return res.json(), sql_data, data - return res.json(), {"sql": None}, data - - @execution_duration(3000) - @log_decorator(True) - def _do_request(self, data: dict, method: str, **kwargs) -> tuple: - """ - request的请求的封装 - :param InData: - :param kwargs: - :return: - """ - # 判断测试数据为字典类型 - if isinstance(data, dict): - if data['requestType'] == Transmission.JSON: - res = requests.request(method=method, url=data["url"], json=data['data'], - headers=data['headers'], **kwargs) - - elif data['requestType'] == Transmission.FILE: - res = requests.request(method=method, url=data["url"], files=data['data'], - headers=data['headers'], **kwargs) - - elif data['requestType'] == Transmission.PARAMS: - res = requests.request(method=method, url=data["url"], params=data['data'], - headers=data['headers'], **kwargs) - - else: - res = requests.request(method=method, url=data["url"], data=data['data'], - headers=data['headers'], **kwargs) - - allure.dynamic.title(data['detail']) - allure_step_no(f"请求URL: {data['url']}") - allure_step_no(f"请求方式: {data['method']}") - allure_step("请求头: ", data['headers']) - allure_step("请求数据: ", data['data']) - allure_step("预期数据: ", data['resp']) - allure_step("响应结果: ", res.json()) - allure_step_no(f"响应耗时(s): {res.elapsed.total_seconds()}") - - return self._check_params(res, data) - else: - raise TypeError("InData 需要是 dict类型") - - def http_request(self, method, data, **kwargs) -> tuple: - try: - if method.upper() == 'POST': - return self._do_request(data, data['method'], **kwargs) - elif method.upper() == 'GET': - return self._do_request(data, data['method'], **kwargs) - elif method.upper() == 'DELETE': - return self._do_request(data, data['method'], **kwargs) - elif method.upper() == 'PUT': - return self._do_request(data, data['method'], **kwargs) - else: - raise TypeError(f"请求异常,检查yml文件method") - except Exception: - raise - - -if __name__ == '__main__': - pass diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..34ce75b --- /dev/null +++ b/utils/__init__.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2021/12/14 22:06 +# @Author : 余少琪 + +import datetime +import os +from config.setting import get_current_system, ConfigHandler +from utils.readFilesUtils.yamlControl import GetYamlData + + +def sys_slash(): + # 判断系统路径 + slash = '\\' + + # 判断当前操作系统 + if get_current_system() == 'Linux' or get_current_system() == "Darwin": + slash = '/' + + return slash + + +def sql_switch() -> bool: + """获取数据库开关""" + switch = GetYamlData(ConfigHandler.config_path) \ + .get_yaml_data()['MySqlDB']["switch"] + return switch + + +def get_notification_type(): + # 获取报告通知类型,是发送钉钉还是企业邮箱 + date = GetYamlData(ConfigHandler.config_path).get_yaml_data()['NotificationType'] + return date + + +def write_page_files(class_title, func_title, case_detail, case_path, yaml_path): + """ + 自动写成 py 文件 + :param yaml_path: + :param case_path: 生成的py文件地址 + :param class_title: 类名称, 读取用例中的 caseTitle 作为类名称 + :param func_title: 函数名称 caseTitle,首字母小写 + :param case_detail: 函数描述,读取用例中的描述内容,做为函数描述 + :return: + """ + author = GetYamlData(ConfigHandler.config_path).get_yaml_data()['TestName'] + now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + + page = f'''#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : {now} +# @Author : {author} + + +from tools.requestControl import RequestControl +from tools.yamlControl import GetCaseData +from config.setting import ConfigHandler + + +class {class_title}(object): + @staticmethod + def {func_title}(inData): + """ + {case_detail} + :param inData: + :return: + """ + + resp = RequestControl().HttpRequest(inData['method'], inData) + return resp + + +if __name__ == '__main__': + path = GetCaseData(ConfigHandler.data_path + r'{yaml_path}').get_yaml_case_data()[0] + data = {class_title}().{func_title}(path) + print(data) + ''' + with open(case_path, 'w', encoding="utf-8") as f: + f.write(page) + + +def write_testcase_file(allure_epic, allure_feature, class_title, + func_title, case_path, yaml_path, file_name, allure_story): + """ + + :param allure_story: + :param file_name: 文件名称 + :param allure_epic: 项目名称 + :param allure_feature: 模块名称 + :param class_title: 类名称 + :param func_title: 函数名称 + :param case_path: case 路径 + :param yaml_path: yaml 文件路径 + :return: + """ + author = GetYamlData(ConfigHandler.config_path).get_yaml_data()['TesterName'] + now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + + page = f'''#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : {now} +# @Author : {author} + + +import allure +import pytest +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData +from utils.assertUtils.assertControl import Assert +from utils.requestsUtils.requestControl import RequestControl + + +TestData = CaseData(ConfigHandler.data_path + r'{yaml_path}').case_process() + + +@allure.epic("{allure_epic}") +@allure.feature("{allure_feature}") +class Test{class_title}: + + @allure.story("{allure_story}") + @pytest.mark.parametrize('in_data', TestData, ids=[i['detail'] for i in TestData]) + def test_{func_title}(self, in_data, case_skip): + """ + :param : + :return: + """ + + res = RequestControl().http_request(in_data) + Assert(in_data['assert']).assert_equality(response_data=res[0], sql_data=res[1]) + + +if __name__ == '__main__': + pytest.main(['{file_name}', '-s', '-W', 'ignore:Module already imported:pytest.PytestWarning']) +''' + if not os.path.exists(case_path): + with open(case_path, 'w', encoding="utf-8") as f: + f.write(page) + + +configPath = GetYamlData(ConfigHandler.config_path).get_yaml_data() +project_name = configPath['ProjectName'][0] +tester_name = configPath['TesterName'] + + +if __name__ == '__main__': + allure_attach('1111', '222.txt', '22') \ No newline at end of file diff --git a/utils/__pycache__/__init__.cpython-39.pyc b/utils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..bc248eb Binary files /dev/null and b/utils/__pycache__/__init__.cpython-39.pyc differ diff --git a/utils/assertUtils/__init__.py b/utils/assertUtils/__init__.py new file mode 100644 index 0000000..981c4b5 --- /dev/null +++ b/utils/assertUtils/__init__.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 14:17 +# @Author : 余少琪 + +from config.setting import ConfigHandler +from utils.readFilesUtils.get_yaml_data_analysis import CaseData + + +TestData = CaseData(ConfigHandler.data_path + r'WorkApplyCenter/sup_apply_list.yaml').case_process() + +is_run = [i for i in TestData if i['is_run'] is False] + +print(is_run) \ No newline at end of file diff --git a/utils/assertUtils/__pycache__/__init__.cpython-39.pyc b/utils/assertUtils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..b92f019 Binary files /dev/null and b/utils/assertUtils/__pycache__/__init__.cpython-39.pyc differ diff --git a/utils/assertUtils/__pycache__/assertControl.cpython-39.pyc b/utils/assertUtils/__pycache__/assertControl.cpython-39.pyc new file mode 100644 index 0000000..ddc9699 Binary files /dev/null and b/utils/assertUtils/__pycache__/assertControl.cpython-39.pyc differ diff --git a/utils/assertUtils/assertControl.py b/utils/assertUtils/assertControl.py new file mode 100644 index 0000000..a32c33a --- /dev/null +++ b/utils/assertUtils/assertControl.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 14:18 +# @Author : 余少琪 + + +import jsonpath +from utils import sql_switch +from utils.logUtils.logControl import ERROR, WARNING +from Enums.assertType_enum import AssertType + + +class Assert: + + def __init__(self, assert_data: dict): + self.assert_data = assert_data + + @staticmethod + def _check_params(response_data: dict, sql_data: dict): + """ + + :param response_data: 响应数据 + :param sql_data: 数据库数据 + :return: + """ + # 用例如果不执行,接口返回的相应数据和数据库断言都是 False,这里则判断跳过断言判断 + if response_data is False and sql_data is False: + return False + else: + # 判断断言的数据类型 + if isinstance(response_data, dict) and isinstance(sql_data, dict): + pass + else: + raise ValueError("response_data、sql_data、assert_data的数据类型必须要是字典类型") + + @staticmethod + def _assert_type(key: any, types: str, value: any): + """ + + :param key: + :param types: + :param value: + :return: + """ + try: + if types == AssertType.EQUAL.value: + assert key == value + elif types == AssertType.NOTEQUAL.value: + assert key != value + elif types.upper() == AssertType.IN.value: + assert key in value + elif types.upper() == AssertType.NO_TIN.value: + assert key not in value + + else: + raise ValueError(f"断言失败,目前不支持{types}断言类型,如需新增断言类型,请联系管理员") + # 正常断言的数据,需要则开启 + # INFO.logger.info("断言成功, 预期值:{}, 断言类型{}, 实际值{}".format(value, types, key)) + + except AssertionError: + ERROR.logger.error("断言失败, 预期值:{}, 断言类型{}, 实际值{}".format(value, types, key)) + raise + + def sql_switch_handle(self, sql_data, assert_value, key, values, resp_data) -> None: + """ + + :param sql_data: 测试用例中的sql + :param assert_value: 断言内容 + :param key: + :param values: + :param resp_data: 预期结果 + :return: + """ + # 判断数据库为开关为关闭状态 + if sql_switch() is False: + WARNING.logger.warning(f"检测到数据库状态为关闭状态,程序已为您跳过此断言,断言值:{values}") + # 数据库开关为开启 + if sql_switch(): + # 判断当用例走的数据数据库断言,但是用例中未填写SQL + if sql_data == {'sql': None}: + raise ValueError("请在用例中添加您要查询的SQL语句。") + # 走正常SQL断言逻辑 + else: + res_sql_data = jsonpath.jsonpath(sql_data, assert_value)[0] + # 判断mysql查询出来的数据类型如果是bytes类型,转换成str类型 + if isinstance(res_sql_data, bytes): + res_sql_data = res_sql_data.decode('utf=8') + self._assert_type(types=self.assert_data[key]['type'], key=resp_data[0], value=res_sql_data) + + def assert_type_handle(self, assert_type, sql_data, assert_value, key, values, resp_data) -> None: + # 判断断言类型 + if assert_type == 'SQL': + self.sql_switch_handle(sql_data, assert_value, key, values, resp_data) + # 判断assertType为空的情况下,则走响应断言 + elif assert_type is None: + self._assert_type(types=self.assert_data[key]['type'], key=resp_data[0], value=assert_value) + else: + raise ValueError("断言失败,目前只支持数据库断言和响应断言") + + def assert_equality(self, response_data: dict, sql_data: dict): + # 判断数据类型 + if self._check_params(response_data, sql_data) is not False: + for key, values in self.assert_data.items(): + assert_value = self.assert_data[key]['value'] # 获取 yaml 文件中的期望value值 + assert_jsonpath = self.assert_data[key]['jsonpath'] # 获取到 yaml断言中的jsonpath的数据 + assert_type = self.assert_data[key]['AssertType'] + # 从yaml获取jsonpath,拿到对象的接口响应数据 + resp_data = jsonpath.jsonpath(response_data, assert_jsonpath) + + # jsonpath 如果数据获取失败,会返回False,判断获取成功才会执行如下代码 + if resp_data is not False: + # 判断断言类型 + self.assert_type_handle(assert_type, sql_data, assert_value, key, values, resp_data) + else: + ERROR.logger.error("JsonPath值获取失败{}".format(assert_jsonpath)) + raise ValueError(f"JsonPath值获取失败{assert_jsonpath}") + else: + pass + + +if __name__ == '__main__': + pass diff --git a/utils/cacheUtils/__init__.py b/utils/cacheUtils/__init__.py new file mode 100644 index 0000000..0df9ed8 --- /dev/null +++ b/utils/cacheUtils/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 15:27 +# @Author : 余少琪 diff --git a/utils/cacheUtils/__pycache__/__init__.cpython-39.pyc b/utils/cacheUtils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..0d4450f Binary files /dev/null and b/utils/cacheUtils/__pycache__/__init__.cpython-39.pyc differ diff --git a/utils/cacheUtils/__pycache__/cacheControl.cpython-39.pyc b/utils/cacheUtils/__pycache__/cacheControl.cpython-39.pyc new file mode 100644 index 0000000..6b2a6c6 Binary files /dev/null and b/utils/cacheUtils/__pycache__/cacheControl.cpython-39.pyc differ diff --git a/tools/cacheControl.py b/utils/cacheUtils/cacheControl.py similarity index 59% rename from tools/cacheControl.py rename to utils/cacheUtils/cacheControl.py index af49c94..2aea73c 100644 --- a/tools/cacheControl.py +++ b/utils/cacheUtils/cacheControl.py @@ -1,19 +1,19 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/26 21:56 +# @Time : 2022/3/28 15:28 # @Author : 余少琪 -from config.setting import ConfigHandler + import os from typing import Any -from tools.logControl import ERROR, INFO, WARNING +from config.setting import ConfigHandler class Cache: """ 设置、读取缓存 """ - def __init__(self, filename: str): - self.path = ConfigHandler().cache_path + "/" + filename + '.txt' + def __init__(self, filename: str) -> None: + self.path = ConfigHandler().cache_path + filename - def set_cache(self, key: str, value) -> None: + def set_cache(self, key, value): """ 设置缓存, 只支持设置单字典类型缓存数据, 缓存文件如以存在,则替换之前的缓存内容 :return: @@ -21,18 +21,14 @@ class Cache: with open(self.path, 'w') as f: f.write(str({key: value})) - def set_caches(self, value: dict) -> None: + def set_caches(self, value: any) -> None: """ 设置多组缓存数据 :param value: 缓存内容 :return: """ - if isinstance(value, dict): - with open(self.path, 'w') as f: - f.write(str(value)) - - else: - raise ValueError("缓存类型必须要是 dict 类型") + with open(self.path, 'w') as f: + f.write(str(value)) def get_cache(self) -> Any: """ @@ -42,9 +38,9 @@ class Cache: with open(self.path, 'r') as f: return f.read() - def clean_cache(self): + def clean_cache(self) -> None: if not os.path.exists(self.path): - raise ValueError("您要删除的缓存文件不存在. {0}".format(self.path)) + raise "您要删除的缓存文件不存在. {0}".format(self.path) os.remove(self.path) @classmethod @@ -58,11 +54,8 @@ class Cache: list_dir = os.listdir(cache_path) for i in list_dir: # 循环删除文件夹下得所有内容 - os.remove(cache_path + "/" + i) + os.remove(cache_path + i) if __name__ == '__main__': - Cache('cache').clean_all_cache() - ERROR.logger.error("测试error") - INFO.logger.info("测试info") - WARNING.logger.warning("测试waring") \ No newline at end of file + Cache('cache').set_cache('test', 333) \ No newline at end of file diff --git a/utils/cacheUtils/redisControl.py b/utils/cacheUtils/redisControl.py new file mode 100644 index 0000000..12fffcf --- /dev/null +++ b/utils/cacheUtils/redisControl.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 15:28 +# @Author : 余少琪 + +import redis + + +class RedisHandler: + """ redis 缓存读取封装 """ + + def __init__(self): + self.host = '121.43.35.47' + self.port = 6379 + self.db = 0 + self.password = 123456 + self.charset = 'UTF-8' + self.redis = redis.Redis(self.host, port=self.port, password=self.password, decode_responses=True, db=self.db) + + def set_string(self, name: str, value, ex=None, px=None, nx=False, xx=False) -> None: + """ + 缓存中写入 str(单个) + :param name: 缓存名称 + :param value: 缓存值 + :param ex: 过期时间(秒) + :param px: 过期时间(毫秒) + :param nx: 如果设置为True,则只有name不存在时,当前set操作才执行(新增) + :param xx: 如果设置为True,则只有name存在时,当前set操作才执行(修改) + :return: + """ + self.redis.set(name, value, ex=ex, px=px, nx=nx, xx=xx) + + def key_exit(self, key): + """ + 判断redis中的key是否存在 + :param key: + :return: + """ + + return self.redis.exists(key) + + def incr(self, key): + """ + 使用 incr 方法,处理并发问题 + 当 key 不存在时,则会先初始为 0, 每次调用,则会 +1 + :return: + """ + self.redis.incr(key) + + def get_key(self, name) -> str: + """ + 读取缓存 + :param name: + :return: + """ + return self.redis.get(name) + + def set_many(self, *args, **kwargs): + """ + 批量设置 + 支持如下方式批量设置缓存 + eg: set_many({'k1': 'v1', 'k2': 'v2'}) + set_many(k1="v1", k2="v2") + :return: + """ + self.redis.mset(*args, **kwargs) + + def get_many(self, *args): + """获取多个值""" + results = self.redis.mget(*args) + return results + + def del_all_cache(self): + """清理所有现在的数据""" + for key in self.redis.keys(): + self.del_cache(key) + + def del_cache(self, name): + """ + 删除缓存 + :param name: + :return: + """ + self.redis.delete(name) diff --git a/utils/logUtils/__init__.py b/utils/logUtils/__init__.py new file mode 100644 index 0000000..2954bdd --- /dev/null +++ b/utils/logUtils/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 10:56 +# @Author : 余少琪 diff --git a/utils/logUtils/__pycache__/__init__.cpython-39.pyc b/utils/logUtils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..be8b8d1 Binary files /dev/null and b/utils/logUtils/__pycache__/__init__.cpython-39.pyc differ diff --git a/tools/__pycache__/logControl.cpython-38.pyc b/utils/logUtils/__pycache__/logControl.cpython-39.pyc similarity index 65% rename from tools/__pycache__/logControl.cpython-38.pyc rename to utils/logUtils/__pycache__/logControl.cpython-39.pyc index 126b718..08128b5 100644 Binary files a/tools/__pycache__/logControl.cpython-38.pyc and b/utils/logUtils/__pycache__/logControl.cpython-39.pyc differ diff --git a/utils/logUtils/__pycache__/logDecoratorl.cpython-39.pyc b/utils/logUtils/__pycache__/logDecoratorl.cpython-39.pyc new file mode 100644 index 0000000..c3fcdce Binary files /dev/null and b/utils/logUtils/__pycache__/logDecoratorl.cpython-39.pyc differ diff --git a/utils/logUtils/__pycache__/runTimeDecoratorl.cpython-39.pyc b/utils/logUtils/__pycache__/runTimeDecoratorl.cpython-39.pyc new file mode 100644 index 0000000..082b5a6 Binary files /dev/null and b/utils/logUtils/__pycache__/runTimeDecoratorl.cpython-39.pyc differ diff --git a/tools/logControl.py b/utils/logUtils/logControl.py similarity index 77% rename from tools/logControl.py rename to utils/logUtils/logControl.py index 29939e6..d389aed 100644 --- a/tools/logControl.py +++ b/utils/logUtils/logControl.py @@ -1,11 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/25 13:05 +# @Time : 2022/3/28 10:56 # @Author : 余少琪 import logging -from logging import handlers import colorlog +from logging import handlers from config.setting import ConfigHandler @@ -19,8 +19,8 @@ class LogHandler(object): 'crit': logging.CRITICAL } - def __init__(self, filename, level='info', when='D', back_count=3, fmt='%%(levelname)-8s%(asctime)s%(name)s:%(' - 'filename)s:%(lineno)d %(message)s'): + def __init__(self, filename, level='info', when='D', backCount=3, fmt='%%(levelname)-8s%(asctime)s ' + '%(name)s:%(filename)s:%(lineno)d %(message)s'): self.logger = logging.getLogger(filename) self.log_colors_config = { @@ -43,7 +43,7 @@ class LogHandler(object): # 设置屏幕上显示的格式 sh.setFormatter(formatter) # 往文件里写入#指定间隔时间自动生成文件的处理器 - th = handlers.TimedRotatingFileHandler(filename=filename, when=when, backupCount=back_count, encoding='utf-8') + th = handlers.TimedRotatingFileHandler(filename=filename, when=when, backupCount=backCount, encoding='utf-8') """ #实例化TimedRotatingFileHandler #interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种: @@ -67,15 +67,4 @@ ERROR = LogHandler(ConfigHandler.error_log_path, level='error') WARNING = LogHandler(ConfigHandler.warning_log_path, level='warning') if __name__ == '__main__': - INFO.logger.info("测试") - - # msg = '111' - # log = LogHandler(level='debug') - # log.logger.debug('debug') - # log.logger.info(msg) - # log.logger.warning('警告') - # log.logger.error('报错') - # log.logger.critical('严重') - # LogHandler('error.log', level='error').logger.error('error') - # # is_open = ReadIni(node='log').get_value("run") - # INFO.logger.info("111") + INFO.logger.info("测试") \ No newline at end of file diff --git a/utils/logUtils/logDecoratorl.py b/utils/logUtils/logDecoratorl.py new file mode 100644 index 0000000..f88d798 --- /dev/null +++ b/utils/logUtils/logDecoratorl.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 15:21 +# @Author : 余少琪 + +from functools import wraps +from utils.logUtils.logControl import INFO, WARNING + + +def log_decorator(switch: bool): + """ + 封装日志装饰器, 打印请求信息 + :param switch: 定义日志开关 + :return: + """ + # 判断参数类型是否是 int 类型 + if isinstance(switch, bool): + def decorator(func): + @wraps(func) + def swapper(*args, **kwargs): + # 判断日志为开启状态,才打印日志 + res = func(*args, **kwargs) + # 判断日志开关为开启状态 + if switch: + if res is not None: + _dependent_case = res[2]['dependence_case'] + # 判断如果有依赖数据,则展示 + if _dependent_case is True: + _dependent_case = res[2]['dependence_case_data'] + else: + _dependent_case = "暂无依赖用例数据" + + _is_run = res[2]['is_run'] + # 判断正常打印的日志,控制台输出绿色 + if _is_run is None or _is_run is True: + INFO.logger.info( + f"\n=================================================================================\n" + f"测试标题: {res[2]['detail']}\n" + f"请求方式: {res[2]['method']}\n" + f"请求头: {res[2]['headers']}\n" + f"请求路径: {res[2]['url']}\n" + f"请求内容: {res[2]['data']}\n" + f"依赖测试用例: {_dependent_case}\n" + f"接口响应内容: {res[0]}\n" + f"数据库断言数据: {res[1]}\n" + "=================================================================================" + ) + else: + # 跳过执行的用例,控制台输出黄色 + WARNING.logger.warning( + f"\n=================================================================================\n" + "该条用例跳过执行.\n" + f"测试标题: {res[2]['detail']}\n" + f"请求方式: {res[2]['method']}\n" + f"请求头: {res[2]['headers']}\n" + f"请求路径: {res[2]['url']}\n" + f"请求内容: {res[2]['data']}\n" + f"依赖测试用例: {_dependent_case}\n" + f"接口响应内容: {res[0]}\n" + f"数据库断言数据: {res[1]}\n" + "=================================================================================" + ) + return res + else: + return res + return swapper + + return decorator + else: + raise TypeError("日志开关只能为 Ture 或者 False") diff --git a/tools/runtimeControl.py b/utils/logUtils/runTimeDecoratorl.py similarity index 95% rename from tools/runtimeControl.py rename to utils/logUtils/runTimeDecoratorl.py index 85131bd..411b8fe 100644 --- a/tools/runtimeControl.py +++ b/utils/logUtils/runTimeDecoratorl.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/25 13:04 +# @Time : 2022/3/29 14:43 # @Author : 余少琪 import time -from tools.logControl import ERROR +from utils.logUtils.logControl import ERROR def execution_duration(number: int): diff --git a/utils/mysqlUtils/__init__.py b/utils/mysqlUtils/__init__.py new file mode 100644 index 0000000..9d54794 --- /dev/null +++ b/utils/mysqlUtils/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 10:59 +# @Author : 余少琪 diff --git a/utils/mysqlUtils/__pycache__/__init__.cpython-39.pyc b/utils/mysqlUtils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..e69269d Binary files /dev/null and b/utils/mysqlUtils/__pycache__/__init__.cpython-39.pyc differ diff --git a/utils/mysqlUtils/__pycache__/mysqlControl.cpython-39.pyc b/utils/mysqlUtils/__pycache__/mysqlControl.cpython-39.pyc new file mode 100644 index 0000000..eeceb72 Binary files /dev/null and b/utils/mysqlUtils/__pycache__/mysqlControl.cpython-39.pyc differ diff --git a/utils/mysqlUtils/get_sql_data.py b/utils/mysqlUtils/get_sql_data.py new file mode 100644 index 0000000..9647d6a --- /dev/null +++ b/utils/mysqlUtils/get_sql_data.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 14:34 +# @Author : 余少琪 + diff --git a/tools/mysqlControl.py b/utils/mysqlUtils/mysqlControl.py similarity index 90% rename from tools/mysqlControl.py rename to utils/mysqlUtils/mysqlControl.py index 7e2b078..6040f65 100644 --- a/tools/mysqlControl.py +++ b/utils/mysqlUtils/mysqlControl.py @@ -5,20 +5,19 @@ import pymysql from warnings import filterwarnings -from tools.yamlControl import GetYamlData -from tools.logControl import ERROR -from tools.yamlControl import GetCaseData +from utils.logUtils.logControl import ERROR from config.setting import ConfigHandler -from tools.regularControl import sql_regular +from utils.readFilesUtils.regularControl import sql_regular +from utils.readFilesUtils.yamlControl import GetYamlData +from utils import sql_switch + # 忽略 Mysql 告警信息 filterwarnings("ignore", category=pymysql.Warning) -switch = GetCaseData(ConfigHandler.config_path).get_yaml_data()['MySqlDB']['switch'] - class MysqlDB(object): - if switch: + if sql_switch(): def __init__(self): self.config = GetYamlData(ConfigHandler.config_path) @@ -69,7 +68,7 @@ class MysqlDB(object): except Exception as e: ERROR.logger.error("数据库连接失败,失败原因{0}".format(e)) - def execute(self, sql): + def execute(self, sql: str): """ 更新 、 删除、 新增 :param sql: @@ -118,6 +117,4 @@ class MysqlDB(object): if __name__ == '__main__': - mysql_db = MysqlDB() - a = mysql_db.assert_execution(sql=[""], resp={"code": 237, "value": 1}) - print(a) + pass diff --git a/utils/noticUtils/__pycache__/dingtalkControl.cpython-39.pyc b/utils/noticUtils/__pycache__/dingtalkControl.cpython-39.pyc new file mode 100644 index 0000000..9c004ba Binary files /dev/null and b/utils/noticUtils/__pycache__/dingtalkControl.cpython-39.pyc differ diff --git a/utils/noticUtils/__pycache__/feishuControl.cpython-39.pyc b/utils/noticUtils/__pycache__/feishuControl.cpython-39.pyc new file mode 100644 index 0000000..81ed5ac Binary files /dev/null and b/utils/noticUtils/__pycache__/feishuControl.cpython-39.pyc differ diff --git a/utils/noticUtils/__pycache__/sendmailControl.cpython-39.pyc b/utils/noticUtils/__pycache__/sendmailControl.cpython-39.pyc new file mode 100644 index 0000000..2c0a0f1 Binary files /dev/null and b/utils/noticUtils/__pycache__/sendmailControl.cpython-39.pyc differ diff --git a/utils/noticUtils/__pycache__/weChatSendControl.cpython-39.pyc b/utils/noticUtils/__pycache__/weChatSendControl.cpython-39.pyc new file mode 100644 index 0000000..82a7ae0 Binary files /dev/null and b/utils/noticUtils/__pycache__/weChatSendControl.cpython-39.pyc differ diff --git a/tools/dingtalkControl.py b/utils/noticUtils/dingtalkControl.py similarity index 73% rename from tools/dingtalkControl.py rename to utils/noticUtils/dingtalkControl.py index a7ddad2..8128dbc 100644 --- a/tools/dingtalkControl.py +++ b/utils/noticUtils/dingtalkControl.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/25 13:15 +# @Time : 2022/3/28 15:30 # @Author : 余少琪 import base64 @@ -8,12 +8,13 @@ import hashlib import hmac import time import urllib.parse -from tools.yamlControl import GetYamlData +from typing import Any +from utils.readFilesUtils.yamlControl import GetYamlData from dingtalkchatbot.chatbot import DingtalkChatbot, FeedLink from config.setting import ConfigHandler -from typing import Any -from tools.allureDataControl import CaseCount -from tools.localIpControl import get_host_ip +from utils.otherUtils.localIpControl import get_host_ip +from utils.otherUtils.allureDate.allure_report_data import CaseCount +from utils import project_name, tester_name class DingTalkSendMsg(object): @@ -28,15 +29,7 @@ class DingTalkSendMsg(object): # 获取 webhook地址 self.webhook = self.getDingTalk["webhook"] + "×tamp=" + self.timeStamp + "&sign=" + self.sign self.xiaoDing = DingtalkChatbot(self.webhook) - self.name = GetYamlData(ConfigHandler.config_path).get_yaml_data()['ProjectName'][0] - self.tester = GetYamlData(ConfigHandler.config_path).get_yaml_data()['TestName'] - self.allureData = CaseCount() - self.PASS = self.allureData.pass_count() - self.FAILED = self.allureData.failed_count() - self.BROKEN = self.allureData.broken_count() - self.SKIP = self.allureData.skipped_count() - self.TOTAL = self.allureData.total_count() - self.RATE = self.allureData.pass_rate() + self.Process = CaseCount() def get_sign(self) -> str: """ @@ -74,9 +67,10 @@ class DingTalkSendMsg(object): except Exception: raise - def send_markdown(self, title: str, msg: str, mobiles=None) -> None: + def send_markdown(self, title: str, msg: str, mobiles=None, is_at_all=False) -> None: """ + :param is_at_all: :param mobiles: :param title: :param msg: @@ -84,7 +78,7 @@ class DingTalkSendMsg(object): """ if mobiles is None: - self.xiaoDing.send_markdown(title=title, text=msg, is_at_all=True) + self.xiaoDing.send_markdown(title=title, text=msg, is_at_all=is_at_all) else: if isinstance(mobiles, list): self.xiaoDing.send_markdown(title=title, text=msg, at_mobiles=mobiles) @@ -104,9 +98,10 @@ class DingTalkSendMsg(object): def send_ding_notification(self): # 发送钉钉通知 - text = f"#### {self.name}自动化通知 \n\n>Python脚本任务: {self.name}\n\n>环境: TEST\n\n>" \ - f"执行人: {self.tester}\n\n>成功率: {self.RATE}% \n\n>总用例数: {self.TOTAL} \n\n>成功用例数: {self.PASS}" \ - f" \n\n>失败用例数: {self.FAILED} \n\n>异常用例数: {self.BROKEN} \n\n>跳过用例数: {self.BROKEN}" \ + text = f"#### {project_name}自动化通知 \n\n>Python脚本任务: {project_name}\n\n>环境: TEST\n\n>" \ + f"执行人: {tester_name}\n\n>执行结果: {self.Process.pass_rate()}% \n\n>总用例数: {self.Process.total_count()} " \ + f"\n\n>成功用例数: {self.Process.pass_rate()}" \ + f" \n\n>失败用例数: {self.Process.failed_count()} \n\n>跳过用例数: {self.Process.skipped_count()}" \ f" ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n" \ f" > ###### 测试报告 [详情](http://{get_host_ip()}:9999/index.html) \n" DingTalkSendMsg().send_markdown( @@ -117,5 +112,4 @@ class DingTalkSendMsg(object): if __name__ == '__main__': - d = DingTalkSendMsg() - print(d.send_ding_notification()) + DingTalkSendMsg().send_ding_notification() diff --git a/utils/noticUtils/feishuControl.py b/utils/noticUtils/feishuControl.py new file mode 100644 index 0000000..577913d --- /dev/null +++ b/utils/noticUtils/feishuControl.py @@ -0,0 +1,220 @@ +from json import JSONDecodeError +import requests +import json +import logging +import time +import urllib3 +import datetime + +from config.setting import ConfigHandler +from utils.readFilesUtils.yamlControl import GetYamlData +from utils.otherUtils.allureDate.allure_report_data import CaseCount + +urllib3.disable_warnings() + +try: + JSONDecodeError = json.decoder.JSONDecodeError +except AttributeError: + JSONDecodeError = ValueError + + +def is_not_null_and_blank_str(content): + """ + 非空字符串 + :param content: 字符串 + :return: 非空 - True,空 - False + """ + if content and content.strip(): + return True + else: + return False + + +class FeiShuTalkChatBot(object): + """飞书机器人通知""" + def __init__(self): + + self.timeStamp = str(round(time.time() * 1000)) + self.devConfig = ConfigHandler() + # 从yaml文件中获取钉钉配置信息 + + self.name = GetYamlData(ConfigHandler.config_path).get_yaml_data()['ProjectName'][0] + self.test_name = GetYamlData(ConfigHandler.config_path).get_yaml_data()['TesterName'] + self.host = GetYamlData(ConfigHandler.config_path).get_yaml_data()['Env'] + self.tester = GetYamlData(ConfigHandler.config_path).get_yaml_data() + self.allure_data = CaseCount() + self.PASS = self.allure_data.pass_count() + self.FAILED = self.allure_data.failed_count() + self.BROKEN = self.allure_data.broken_count() + self.SKIP = self.allure_data.skipped_count() + self.TOTAL = self.allure_data.total_count() + self.RATE = self.allure_data.pass_rate() + + self.headers = {'Content-Type': 'application/json; charset=utf-8'} + self.devConfig = ConfigHandler() + self.getFeiShuTalk = GetYamlData(self.devConfig.config_path).get_yaml_data()['FeiShuTalk'] + self.webhook = self.getFeiShuTalk["webhook"] + + def send_text(self, msg: str): + """ + 消息类型为text类型 + :param msg: 消息内容 + :return: 返回消息发送结果 + """ + data = {"msg_type": "text", "at": {}} + if is_not_null_and_blank_str(msg): # 传入msg非空 + data["content"] = {"text": msg} + else: + logging.error("text类型,消息内容不能为空!") + raise ValueError("text类型,消息内容不能为空!") + + logging.debug('text类型:%s' % data) + return self.post() + + def post(self): + """ + 发送消息(内容UTF-8编码) + :return: 返回消息发送结果 + """ + rich_text = { + "email": "fanlv@bytedance.com", + "msg_type": "post", + "content": { + "post": { + "zh_cn": { + "title": "【自动化测试通知】", + "content": [ + [ + { + "tag": "a", + "text": "测试报告", + "href": "http://192.168.0.72:8080/job/helper_test_adverte/allure/#" + }, + { + "tag": "at", + "user_id": "ou_18eac85d35a26f989317ad4f02e8bbbb" + # "text":"陈锐男" + } + ], + [ + { + "tag": "text", + "text": "测试 人员 : " + }, + { + "tag": "text", + "text": "{testname}".format(testname=self.test_name) + } + ], + [ + { + "tag": "text", + "text": "运行 环境 : " + }, + { + "tag": "text", + "text": "{host}".format(host=str(self.host)) + } + ], + [{ + "tag": "text", + "text": "成 功 率 : " + }, + { + "tag": "text", + "text": "{rate}".format(rate=self.RATE) + " %" + }], # 成功率 + + [{ + "tag": "text", + "text": "成功用例数 : " + }, + { + "tag": "text", + "text": "{total}".format(total=self.PASS) + }], # 成功用例数 + + [{ + "tag": "text", + "text": "失败用例数 : " + }, + { + "tag": "text", + "text": "{failed}".format(failed=self.FAILED) + }], # 失败用例数 + [{ + "tag": "text", + "text": "异常用例数 : " + }, + { + "tag": "text", + "text": "{failed}".format(failed=self.BROKEN) + }], # 损坏用例数 + [ + { + "tag": "text", + "text": "时 间 : " + }, + { + "tag": "text", + "text": "{test}".format(test=datetime.datetime.now().strftime('%Y-%m-%d')) + } + ], + + [ + { + "tag": "img", + "image_key": "d640eeea-4d2f-4cb3-88d8-c964fab53987", + "width": 300, + "height": 300 + } + ] + ] + } + } + } + } + try: + post_data = json.dumps(rich_text) + response = requests.post(self.webhook, headers=self.headers, data=post_data, verify=False) + except requests.exceptions.HTTPError as exc: + logging.error("消息发送失败, HTTP error: %d, reason: %s" % (exc.response.status_code, exc.response.reason)) + raise + except requests.exceptions.ConnectionError: + logging.error("消息发送失败,HTTP connection error!") + raise + except requests.exceptions.Timeout: + logging.error("消息发送失败,Timeout error!") + raise + except requests.exceptions.RequestException: + logging.error("消息发送失败, Request Exception!") + raise + else: + try: + result = response.json() + except JSONDecodeError: + logging.error("服务器响应异常,状态码:%s,响应内容:%s" % (response.status_code, response.text)) + return {'errcode': 500, 'errmsg': '服务器响应异常'} + else: + logging.debug('发送结果:%s' % result) + # 消息发送失败提醒(errcode 不为 0,表示消息发送异常),默认不提醒,开发者可以根据返回的消息发送结果自行判断和处理 + if result.get('StatusCode') != 0: + time_now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) + error_data = { + "msgtype": "text", + "text": { + "content": "[注意-自动通知]飞书机器人消息发送失败,时间:%s,原因:%s,请及时跟进,谢谢!" % ( + time_now, result['errmsg'] if result.get('errmsg', False) else '未知异常') + }, + "at": { + "isAtAll": False + } + } + logging.error("消息发送失败,自动通知:%s" % error_data) + requests.post(self.webhook, headers=self.headers, data=json.dumps(error_data)) + return result + + +if __name__ == '__main__': + send = FeiShuTalkChatBot() + send.post() diff --git a/tools/sendmailControl.py b/utils/noticUtils/sendmailControl.py similarity index 82% rename from tools/sendmailControl.py rename to utils/noticUtils/sendmailControl.py index 24460c1..74dcec9 100644 --- a/tools/sendmailControl.py +++ b/utils/noticUtils/sendmailControl.py @@ -1,14 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/25 16:20 +# @Time : 2022/3/29 14:57 # @Author : 余少琪 - import smtplib from email.mime.text import MIMEText -from tools.yamlControl import GetYamlData from config.setting import ConfigHandler -from tools.allureDataControl import CaseCount, AllureFileClean +from utils.readFilesUtils.yamlControl import GetYamlData +from utils.otherUtils.allureDate.allure_report_data import CaseCount, AllureFileClean class SendEmail(object): @@ -16,7 +15,7 @@ class SendEmail(object): self.getData = GetYamlData(ConfigHandler.config_path).get_yaml_data()['email'] self.send_user = self.getData['send_user'] # 发件人 self.email_host = self.getData['email_host'] # QQ 邮件 STAMP 服务器地址 - self.key = self.getData['stmp_key'] # STAMP 授权码 + self.key = self.getData['stamp_key'] # STAMP 授权码 self.name = GetYamlData(ConfigHandler.config_path).get_yaml_data()['ProjectName'][0] self.allureData = CaseCount() self.PASS = self.allureData.pass_count() @@ -27,7 +26,7 @@ class SendEmail(object): self.RATE = self.allureData.pass_rate() self.CaseDetail = AllureFileClean().get_failed_cases_detail() - def send_mail(self, user_list: list, sub, content): + def send_mail(self, user_list: list, sub, content: str) -> None: """ @param user_list: 发件人邮箱 @@ -46,27 +45,26 @@ class SendEmail(object): server.sendmail(user, user_list, message.as_string()) server.close() - def error_mail(self, error_message): + def error_mail(self, error_message: str) -> None: """ 执行异常邮件通知 @param error_message: 报错信息 @return: """ - emali = self.getData['send_list'] - user_list = emali.split(',') # 多个邮箱发送,config文件中直接添加 '806029174@qq.com' + email = self.getData['send_list'] + user_list = email.split(',') # 多个邮箱发送,config文件中直接添加 '806029174@qq.com' sub = self.name + "接口自动化执行异常通知" content = "自动化测试执行完毕,程序中发现异常,请悉知。报错信息如下:\n{0}".format(error_message) self.send_mail(user_list, sub, content) - def send_main(self): + def send_main(self) -> None: """ 发送邮件 :return: """ - - emali = self.getData["send_list"] - user_list = emali.split(',') # 多个邮箱发送,yaml文件中直接添加 '806029174@qq.com' + email = self.getData["send_list"] + user_list = email.split(',') # 多个邮箱发送,yaml文件中直接添加 '806029174@qq.com' sub = self.name + "接口自动化报告" content = """ @@ -78,7 +76,7 @@ class SendEmail(object): 异常用例个数: {} 个 跳过用例个数: {} 个 成 功 率: {} % - + {} ********************************** diff --git a/tools/weChatSendControl.py b/utils/noticUtils/weChatSendControl.py similarity index 88% rename from tools/weChatSendControl.py rename to utils/noticUtils/weChatSendControl.py index 3a37003..8b08952 100644 --- a/tools/weChatSendControl.py +++ b/utils/noticUtils/weChatSendControl.py @@ -1,17 +1,17 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2022/2/21 17:33 +# @Time : 2022/3/29 14:59 # @Author : 余少琪 -from config.setting import ConfigHandler -from tools.yamlControl import GetYamlData import requests -from tools.logControl import ERROR -from tools.allureDataControl import CaseCount -from tools.gettimeControl import now_time -from tools.localIpControl import get_host_ip - +from config.setting import ConfigHandler +from utils.readFilesUtils.yamlControl import GetYamlData +from utils.logUtils.logControl import ERROR +from utils.otherUtils.allureDate.allure_report_data import CaseCount +from utils.timesUtils.timeControl import NowTime +from utils.otherUtils.localIpControl import get_host_ip +from utils import project_name, tester_name class WeChatSend: """ @@ -22,8 +22,6 @@ class WeChatSend: self.weChatData = GetYamlData(ConfigHandler.config_path).get_yaml_data()['WeChat'] self.curl = self.weChatData['webhook'] self.headers = {"Content-Type": "application/json"} - self.name = GetYamlData(ConfigHandler.config_path).get_yaml_data()['ProjectName'][0] - self.tester = GetYamlData(ConfigHandler.config_path).get_yaml_data()['TestName'] self.allureData = CaseCount() self.PASS = self.allureData.pass_count() self.FAILED = self.allureData.failed_count() @@ -97,7 +95,7 @@ class WeChatSend: else: raise TypeError("图文类型的参数必须是字典类型") - def send_email_notification(self): + def send_wechat_notification(self): # 发送企业微信通知 text = """【{0}自动化通知】 >测试环境:TEST @@ -113,11 +111,11 @@ class WeChatSend: > >非相关负责人员可忽略此消息。 >测试报告,点击查看>>[测试报告入口](http://{6}:9999/index.html)""" \ - .format(self.name, self.tester, self.RATE, self.PASS, self.FAILED, - self.BROKEN, self.SKIP, now_time(), get_host_ip()) + .format(project_name, tester_name, self.RATE, self.PASS, self.FAILED, + self.BROKEN, self.SKIP, NowTime(), get_host_ip()) WeChatSend().send_markdown(text) if __name__ == '__main__': - WeChatSend().send_email_notification() + WeChatSend().send_wechat_notification() \ No newline at end of file diff --git a/utils/otherUtils/__init__.py b/utils/otherUtils/__init__.py new file mode 100644 index 0000000..8066f34 --- /dev/null +++ b/utils/otherUtils/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 15:37 +# @Author : 余少琪 diff --git a/utils/otherUtils/__pycache__/__init__.cpython-39.pyc b/utils/otherUtils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..8ba98b4 Binary files /dev/null and b/utils/otherUtils/__pycache__/__init__.cpython-39.pyc differ diff --git a/utils/otherUtils/__pycache__/localIpControl.cpython-39.pyc b/utils/otherUtils/__pycache__/localIpControl.cpython-39.pyc new file mode 100644 index 0000000..c9291dc Binary files /dev/null and b/utils/otherUtils/__pycache__/localIpControl.cpython-39.pyc differ diff --git a/utils/otherUtils/allureDate/__init__.py b/utils/otherUtils/allureDate/__init__.py new file mode 100644 index 0000000..a399eb2 --- /dev/null +++ b/utils/otherUtils/allureDate/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 15:44 +# @Author : 余少琪 diff --git a/utils/otherUtils/allureDate/__pycache__/__init__.cpython-39.pyc b/utils/otherUtils/allureDate/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..bfef13f Binary files /dev/null and b/utils/otherUtils/allureDate/__pycache__/__init__.cpython-39.pyc differ diff --git a/utils/otherUtils/allureDate/__pycache__/allure_report_data.cpython-39.pyc b/utils/otherUtils/allureDate/__pycache__/allure_report_data.cpython-39.pyc new file mode 100644 index 0000000..2ef140c Binary files /dev/null and b/utils/otherUtils/allureDate/__pycache__/allure_report_data.cpython-39.pyc differ diff --git a/utils/otherUtils/allureDate/__pycache__/allure_tools.cpython-39.pyc b/utils/otherUtils/allureDate/__pycache__/allure_tools.cpython-39.pyc new file mode 100644 index 0000000..e043016 Binary files /dev/null and b/utils/otherUtils/allureDate/__pycache__/allure_tools.cpython-39.pyc differ diff --git a/tools/allureDataControl.py b/utils/otherUtils/allureDate/allure_report_data.py similarity index 61% rename from tools/allureDataControl.py rename to utils/otherUtils/allureDate/allure_report_data.py index aa67073..e95767d 100644 --- a/tools/allureDataControl.py +++ b/utils/otherUtils/allureDate/allure_report_data.py @@ -1,49 +1,37 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2022/2/23 18:15 +# @Time : 2022/3/28 15:44 # @Author : 余少琪 -import json -from setting import ConfigHandler -import os +import json +from config.setting import ConfigHandler +from utils.readFilesUtils.get_all_files_path import get_all_files class AllureFileClean: """allure 报告数据清洗,提取业务需要得数据""" - def __init__(self): - pass - @classmethod - def _get_al_files(cls) -> list: - """ 获取所有 test-case 中的 json 文件 """ - filename = [] - # 获取所有文件下的子文件名称 - for root, dirs, files in os.walk(ConfigHandler.report_path + '/html/data/test-cases'): - for filePath in files: - path = os.path.join(root, filePath) - filename.append(path) - return filename - - def get_test_cases(self): + def get_testcases(cls) -> list: """ 获取所有 allure 报告中执行用例的情况""" # 将所有数据都收集到files中 files = [] - for i in self._get_al_files(): + for i in get_all_files(ConfigHandler.report_path): with open(i, 'r', encoding='utf-8') as fp: date = json.load(fp) files.append(date) + print(files) return files - def get_failed_case(self): + def get_failed_case(self) -> list: """ 获取到所有失败的用例标题和用例代码路径""" - error_cases = [] - for i in self.get_test_cases(): + error_case = [] + for i in self.get_testcases(): if i['status'] == 'failed' or i['status'] == 'broken': - error_cases.append((i['name'], i['fullName'])) - return error_cases + error_case.append((i['name'], i['fullName'])) + return error_case - def get_failed_cases_detail(self): + def get_failed_cases_detail(self) -> str: """ 返回所有失败的测试用例相关内容 """ date = self.get_failed_case() # 判断有失败用例,则返回内容 @@ -58,11 +46,11 @@ class AllureFileClean: return "" @classmethod - def get_case_count(cls): + def get_case_count(cls) -> dict: """ 统计用例数量 """ - file_name = ConfigHandler.report_path + '/html/history/history-trend.json' - with open(file_name, 'r', encoding='utf-8') as fp: - date = json.load(fp)[0]['data'] + fil_name = ConfigHandler.report_path + '/html/widgets/summary.json' + with open(fil_name, 'r', encoding='utf-8') as fp: + date = json.load(fp)['statistic'] return date @@ -70,27 +58,27 @@ class CaseCount: def __init__(self): self.AllureData = AllureFileClean() - def pass_count(self): + def pass_count(self) -> int: """用例成功数""" return self.AllureData.get_case_count()['passed'] - def failed_count(self): + def failed_count(self) -> int: """用例失败数""" return self.AllureData.get_case_count()['failed'] - def broken_count(self): + def broken_count(self) -> int: """用例异常数""" return self.AllureData.get_case_count()['broken'] - def skipped_count(self): + def skipped_count(self) -> int: """用例跳过数""" return self.AllureData.get_case_count()['skipped'] - def total_count(self): + def total_count(self) -> int: """用例总数""" return self.AllureData.get_case_count()['total'] - def pass_rate(self): + def pass_rate(self) -> float: """用例成功率""" # 四舍五入,保留2位小数 try: @@ -101,5 +89,5 @@ class CaseCount: if __name__ == '__main__': - data = AllureFileClean().get_case_count() - print(data) + data = CaseCount().pass_count() + print(data) \ No newline at end of file diff --git a/utils/otherUtils/allureDate/allure_tools.py b/utils/otherUtils/allureDate/allure_tools.py new file mode 100644 index 0000000..b9ba191 --- /dev/null +++ b/utils/otherUtils/allureDate/allure_tools.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/4/7 17:53 +# @Author : 余少琪 + +import allure +import json +from Enums.allureAttchementType_enum import AllureAttachmentType + + +def allure_step(step: str, var: str) -> None: + """ + :param step: 步骤及附件名称 + :param var: 附件内容 + """ + with allure.step(step): + allure.attach( + json.dumps( + str(var), + ensure_ascii=False, + indent=4), + step, + allure.attachment_type.JSON) + + +def allure_attach(source: str, name: str, extension: str): + """ + allure报告上传附件、图片、excel等 + :param source: 文件路径,相当于传一个文件 + :param name: 附件名称 + :param extension: 附件的拓展名称 + :return: + """ + # 获取上传附件的尾缀,判断对应的 attachment_type 枚举值 + _NAME = name.split('.')[-1] + attachment_type = None + if _NAME == AllureAttachmentType.TEXT.value: + attachment_type = allure.attachment_type.TEXT + elif _NAME == AllureAttachmentType.CSV.value: + attachment_type = allure.attachment_type.CSV + elif _NAME == AllureAttachmentType.TSV.value: + attachment_type = allure.attachment_type.TSV + elif _NAME == AllureAttachmentType.URI_LIST.value: + attachment_type = allure.attachment_type.URI_LIST + elif _NAME == AllureAttachmentType.HTML.value: + attachment_type = allure.attachment_type.HTML + elif _NAME == AllureAttachmentType.XML.value: + attachment_type = allure.attachment_type.XML + elif _NAME == AllureAttachmentType.PCAP.value: + attachment_type = allure.attachment_type.PCAP + elif _NAME == AllureAttachmentType.PNG.value: + attachment_type = allure.attachment_type.PNG + elif _NAME == AllureAttachmentType.JPG.value: + attachment_type = allure.attachment_type.JPG + elif _NAME == AllureAttachmentType.SVG.value: + attachment_type = allure.attachment_type.SVG + elif _NAME == AllureAttachmentType.GIF.value: + attachment_type = allure.attachment_type.GIF + elif _NAME == AllureAttachmentType.BMP.value: + attachment_type = allure.attachment_type.BMP + elif _NAME == AllureAttachmentType.TIFF.value: + attachment_type = allure.attachment_type.TIFF + elif _NAME == AllureAttachmentType.MP4.value: + attachment_type = allure.attachment_type.MP4 + elif _NAME == AllureAttachmentType.OGG.value: + attachment_type = allure.attachment_type.OGG + elif _NAME == AllureAttachmentType.WEBM.value: + attachment_type = allure.attachment_type.WEBM + elif _NAME == AllureAttachmentType.SVG.PDF: + attachment_type = allure.attachment_type.PDF + # else: + # raise ValueError(f"allure暂不支持该文件类型, 文件路径: {source}") + allure.attach.file(source=source, name=name, attachment_type=attachment_type, extension=extension) + + +def allure_step_no(step: str): + """ + 无附件的操作步骤 + :param step: 步骤名称 + :return: + """ + with allure.step(step): + pass diff --git a/tools/localIpControl.py b/utils/otherUtils/localIpControl.py similarity index 72% rename from tools/localIpControl.py rename to utils/otherUtils/localIpControl.py index f364e5f..2c832a4 100644 --- a/tools/localIpControl.py +++ b/utils/otherUtils/localIpControl.py @@ -1,12 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/12/14 16:12 +# @Time : 2022/3/28 15:41 # @Author : 余少琪 import socket -def get_host_ip() -> str: +def get_host_ip(): """ 查询本机ip地址 :return: @@ -19,8 +19,4 @@ def get_host_ip() -> str: finally: s.close() - return ip - - -if __name__ == '__main__': - print(get_host_ip()) \ No newline at end of file + return ip \ No newline at end of file diff --git a/tools/threadControl.py b/utils/otherUtils/threadControl.py similarity index 98% rename from tools/threadControl.py rename to utils/otherUtils/threadControl.py index af6cd0e..9d7d4c7 100644 --- a/tools/threadControl.py +++ b/utils/otherUtils/threadControl.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2022/1/25 18:27 +# @Time : 2022/3/28 10:52 # @Author : 余少琪 diff --git a/utils/readFilesUtils/__pycache__/get_all_files_path.cpython-39.pyc b/utils/readFilesUtils/__pycache__/get_all_files_path.cpython-39.pyc new file mode 100644 index 0000000..4048abe Binary files /dev/null and b/utils/readFilesUtils/__pycache__/get_all_files_path.cpython-39.pyc differ diff --git a/utils/readFilesUtils/__pycache__/get_yaml_data_analysis.cpython-39.pyc b/utils/readFilesUtils/__pycache__/get_yaml_data_analysis.cpython-39.pyc new file mode 100644 index 0000000..4fb5f66 Binary files /dev/null and b/utils/readFilesUtils/__pycache__/get_yaml_data_analysis.cpython-39.pyc differ diff --git a/utils/readFilesUtils/__pycache__/regularControl.cpython-39.pyc b/utils/readFilesUtils/__pycache__/regularControl.cpython-39.pyc new file mode 100644 index 0000000..f5b708f Binary files /dev/null and b/utils/readFilesUtils/__pycache__/regularControl.cpython-39.pyc differ diff --git a/utils/readFilesUtils/__pycache__/yamlControl.cpython-39.pyc b/utils/readFilesUtils/__pycache__/yamlControl.cpython-39.pyc new file mode 100644 index 0000000..cdd28b0 Binary files /dev/null and b/utils/readFilesUtils/__pycache__/yamlControl.cpython-39.pyc differ diff --git a/tools/testcaseAutomaticControl.py b/utils/readFilesUtils/caseAutomaticControl.py similarity index 50% rename from tools/testcaseAutomaticControl.py rename to utils/readFilesUtils/caseAutomaticControl.py index 2d6e890..8c39ea6 100644 --- a/tools/testcaseAutomaticControl.py +++ b/utils/readFilesUtils/caseAutomaticControl.py @@ -1,12 +1,14 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/29 15:38 +# @Time : 2022/3/28 13:22 # @Author : 余少琪 import os from config.setting import ConfigHandler -from tools.yamlControl import GetYamlData -from tools import writePageFiles, writeTestCaseFile +from utils import write_testcase_file +from utils.readFilesUtils.yamlControl import GetYamlData +from utils import sys_slash +from utils.readFilesUtils.get_all_files_path import get_all_files class TestCaseAutomaticGeneration: @@ -16,29 +18,17 @@ class TestCaseAutomaticGeneration: def __init__(self): pass - @classmethod - def _get_all_files(cls): - """ 获取所有 yaml 文件 """ - filename = [] - # 获取所有文件下的子文件名称 - for root, dirs, files in os.walk(ConfigHandler.data_path): - for filePath in files: - path = os.path.join(root, filePath) - if '.yaml' in path: - filename.append(path) - return filename - @classmethod def case_date_path(cls) -> str: """返回 yaml 用例文件路径""" return ConfigHandler.data_path @classmethod - def case_path(cls): + def case_path(cls) -> str: """ 存放用例代码路径""" return ConfigHandler.case_path - def file_name(self, file): + def file_name(self, file: str) -> str: """ 通过 yaml文件的命名,将名称转换成 py文件的名称 :param file: yaml 文件路径 @@ -48,10 +38,9 @@ class TestCaseAutomaticGeneration: yaml_path = file[i:] # 路径转换 file_name = yaml_path.replace('.yaml', '.py') - return file_name - def lib_page_path(self, file_path): + def lib_page_path(self, file_path: str) -> str: """ 根据 yaml中的用例数据,生成对应分成中 lib 层代码路径 :param file_path: yaml用例路径 @@ -59,13 +48,13 @@ class TestCaseAutomaticGeneration: """ return ConfigHandler.lib_path + self.file_name(file_path) - def get_package_path(self, file_path): + def get_package_path(self, file_path: str) -> str: """ 根据不同的层级,获取 test_case 中需要依赖的包 :return: from lib.test_demo import DateDemo """ lib_path = self.file_name(file_path) - i = lib_path.split("\\") + i = lib_path.split(sys_slash()) # 判断多层目录下的导报结构 if len(i) > 1: package_path = "from lib" @@ -81,20 +70,22 @@ class TestCaseAutomaticGeneration: elif len(i) == 1: return f"from lib.{i[0][:-3]} import {i[0][:-3]}" - def test_case_path(self, file_path): + def get_case_path(self, file_path: str) -> tuple: """ 根据 yaml 中的用例,生成对应 testCase 层代码的路径 :param file_path: yaml用例路径 - :return: D:\\Project\\test_case\\test_case_demo.py + :return: D:\\Project\\test_case\\test_case_demo.py, test_case_demo.py """ - path = self.file_name(file_path).split('\\') + + # 这里通过“\\” 符号进行分割,提取出来文件名称 + path = self.file_name(file_path).split(sys_slash()) # 判断生成的 testcase 文件名称,需要以test_ 开头 case_name = path[-1] = path[-1].replace(path[-1], "test_" + path[-1]) - new_name = "\\".join(path) + new_name = sys_slash().join(path) return ConfigHandler.case_path + new_name, case_name @classmethod - def test_case_detail(cls, file_path): + def get_testcase_detail(cls, file_path: str) -> str: """ 获取用例描述 :param file_path: yaml 用例路径 @@ -102,76 +93,93 @@ class TestCaseAutomaticGeneration: """ return GetYamlData(file_path).get_yaml_data()[0]['detail'] - def test_class_title(self, file_path): + def get_test_class_title(self, file_path: str) -> str: """ 自动生成类名称 :param file_path: - :return: + :return: sup_apply_list --> SupApplyList """ - return os.path.split(self.lib_page_path(file_path))[1][:-3] + # 提取文件名称 + _FILE_NAME = os.path.split(self.lib_page_path(file_path))[1][:-3] + _NAME = _FILE_NAME.split("_") + # 将文件名称格式,转换成类名称: sup_apply_list --> SupApplyList + for i in range(len(_NAME)): + _NAME[i] = _NAME[i].capitalize() + _CLASS_NAME = "".join(_NAME) - def func_title(self, file_path): + return _CLASS_NAME + + def func_title(self, file_path: str) -> str: """ 函数名称 :param file_path: yaml 用例路径 :return: """ - _CLASS_NAME = self.test_class_title(file_path) - return _CLASS_NAME[0].lower() + _CLASS_NAME[1:] + + _FILE_NAME = os.path.split(self.lib_page_path(file_path))[1][:-3] + return _FILE_NAME @classmethod - def allure_epic(cls, file_path): + def allure_epic(cls, case_data: dict) -> str: """ 用于 allure 报告装饰器中的内容 @allure.epic("项目名称") - :param file_path: + :param case_data: 用例数据 :return: """ - return GetYamlData(file_path).get_yaml_data()[0]['allureEpic'] + return case_data['case_common']['allureEpic'] @classmethod - def allure_feature(cls, file_path): + def allure_feature(cls, case_data: dict) -> str: """ 用于 allure 报告装饰器中的内容 @allure.feature("模块名称") - :param file_path: + :param case_data: :return: """ - return GetYamlData(file_path).get_yaml_data()[0]['allureFeature'] + return case_data['case_common']['allureFeature'] - def mk_dir(self, file_path): - """ 判断生成自动化代码的路径是否存在,如果不存在,则自动创建 """ - _LibDirPath = os.path.split(self.lib_page_path(file_path))[0] + @classmethod + def allure_story(cls, case_data: dict) -> str: + """ + 用于 allure 报告装饰器中的内容 @allure.story("测试功能") + :param case_data: + :return: + """ + return case_data['case_common']['allureStory'] - _CaseDirPath = os.path.split(self.test_case_path(file_path)[0])[0] - _PathList = [_LibDirPath, _CaseDirPath] - for i in _PathList: - if not os.path.exists(i): - os.makedirs(i) + def mk_dir(self, file_path: str) -> None: + """ 判断生成自动化代码的文件夹路径是否存在,如果不存在,则自动创建 """ + # _LibDirPath = os.path.split(self.libPagePath(filePath))[0] - def yaml_path(self, file_path): + _CaseDirPath = os.path.split(self.get_case_path(file_path)[0])[0] + if not os.path.exists(_CaseDirPath): + os.makedirs(_CaseDirPath) + + def yaml_path(self, file_path: str) -> str: """ 生成动态 yaml 路径, 主要处理业务分层场景 :param file_path: 如业务有多个层级, 则获取到每一层/test_demo/DateDemo.py - :return: + :return: Login/config.yaml """ i = len(self.case_date_path()) - return file_path[i:] + # 兼容 linux 和 window 操作路径 + yaml_path = file_path[i:].replace("\\", "/") + return yaml_path - def test_case_automatic(self): + def get_case_automatic(self) -> None: """ 自动生成 测试代码""" - file_path = self._get_all_files() + file_path = get_all_files(ConfigHandler.data_path) for file in file_path: - # # # 判断文件如果已存在,则不会重复写入 + # 判断用例需要用的文件夹路径是否存在,不存在则创建 self.mk_dir(file) - print(self.get_package_path(file)) - - writePageFiles(self.test_class_title(file), self.func_title(file), self.test_case_detail(file), - self.lib_page_path(file), self.yaml_path(file)) - - writeTestCaseFile(self.allure_epic(file), self.allure_feature(file), self.test_class_title(file), - self.func_title(file), self.test_case_detail(file), self.test_case_path(file)[0], - self.yaml_path(file), self.test_case_path(file)[1], self.get_package_path(file)) + yaml_case_process = GetYamlData(file).get_yaml_data() + write_testcase_file( + allure_epic=self.allure_epic(yaml_case_process), allure_feature=self.allure_feature(yaml_case_process), + class_title=self.get_test_class_title(file), func_title=self.func_title(file), + case_path=self.get_case_path(file)[0], yaml_path=self.yaml_path(file), + file_name=self.get_case_path(file)[1], allure_story=self.allure_story(yaml_case_process) + ) if __name__ == '__main__': - TestCaseAutomaticGeneration().test_case_automatic() + TestCaseAutomaticGeneration().get_case_automatic() diff --git a/utils/readFilesUtils/clean_files.py b/utils/readFilesUtils/clean_files.py new file mode 100644 index 0000000..794b818 --- /dev/null +++ b/utils/readFilesUtils/clean_files.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/4/7 11:56 +# @Author : 余少琪 + +import os + + +def del_file(path): + """删除目录下的文件""" + ls = os.listdir(path) + for i in ls: + c_path = os.path.join(path, i) + if os.path.isdir(c_path): + del_file(c_path) + else: + os.remove(c_path) + diff --git a/tools/excelControl.py b/utils/readFilesUtils/excelControl.py similarity index 77% rename from tools/excelControl.py rename to utils/readFilesUtils/excelControl.py index 9efa7ba..6ca9839 100644 --- a/tools/excelControl.py +++ b/utils/readFilesUtils/excelControl.py @@ -1,7 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/19 12:35 +# @Time : 2022/3/28 15:26 # @Author : 余少琪 + import json import xlrd @@ -18,7 +19,7 @@ def get_excel_data(sheet_name: str, case_name: any) -> list: """ res_list = [] - excel_dire = ConfigHandler.excel_path + 'Login.xls' + excel_dire = ConfigHandler.data_path + 'TestLogin.xls' work_book = xlrd.open_workbook(excel_dire, formatting_info=True) # 打开对应的子表 @@ -32,23 +33,21 @@ def get_excel_data(sheet_name: str, case_name: any) -> list: resp_data = work_sheet.cell(idx, 11).value res_list.append((req_body_data, json.loads(resp_data))) idx += 1 - print(res_list) return res_list -def set_excel_data(sheet_index: int) -> tuple: +def set_excelData(sheetIndex: int) -> tuple: """ excel 写入 :return: """ - excel_dir = r'..\data\Login.xls' - work_book = xlrd.open_workbook(excel_dir, formatting_info=True) + excel_dire = '../data/TestLogin.xls' + work_book = xlrd.open_workbook(excel_dire, formatting_info=True) work_book_new = copy(work_book) - work_sheet_new = work_book_new.get_sheet(sheet_index) + work_sheet_new = work_book_new.get_sheet(sheetIndex) return work_book_new, work_sheet_new if __name__ == '__main__': get_excel_data("登录", 'Login001') - diff --git a/utils/readFilesUtils/get_all_files_path.py b/utils/readFilesUtils/get_all_files_path.py new file mode 100644 index 0000000..2eaa86d --- /dev/null +++ b/utils/readFilesUtils/get_all_files_path.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 13:22 +# @Author : 余少琪 +import os + + +def get_all_files(file_path) -> list: + """ 获取所有 yaml 文件 """ + filename = [] + # 获取所有文件下的子文件名称 + for root, dirs, files in os.walk(file_path): + for filePath in files: + path = os.path.join(root, filePath) + if '.yaml' in path: + filename.append(path) + return filename diff --git a/utils/readFilesUtils/get_yaml_data_analysis.py b/utils/readFilesUtils/get_yaml_data_analysis.py new file mode 100644 index 0000000..597dfd9 --- /dev/null +++ b/utils/readFilesUtils/get_yaml_data_analysis.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/22 13:45 +# @Author : 余少琪 + +from utils import sql_switch +from utils.readFilesUtils.yamlControl import GetCaseData + + +class CaseData: + """ + yaml 数据解析, 判断数据填写是否符合规范 + """ + + def __init__(self, file_path): + self.filePath = file_path + + def case_process(self, case_id_switch=None): + """ + 数据清洗之后,返回该 yaml 文件中的所有用例 + :param case_id_switch: 判断数据清洗,是否需要清洗出 case_id, 主要用于兼容用例池中的数据 + :return: + """ + dates = GetCaseData(self.filePath).get_yaml_case_data() + case_lists = [] + for key, values in dates.items(): + # 公共配置中的数据,与用例数据不同,需要单独处理 + if key != 'case_common': + case_date = { + 'method': self.get_case_method(key, values), + 'is_run': self.get_is_run(key, values), + 'url': self.get_case_host(key, values), + 'detail': self.get_case_detail(values), + 'headers': self.get_headers(key, values), + 'requestType': self.get_request_type(key, values), + 'data': self.get_case_dates(key, values), + 'dependence_case': self.get_dependence_case(key, values), + 'dependence_case_data': self.get_dependence_case_data(key, values), + "sql": self.get_sql(key, values), + "assert": self.get_assert(key, values) + } + if case_id_switch is True: + case_lists.append({key: case_date}) + else: + case_lists.append(case_date) + return case_lists + + def get_case_host(self, case_id: str, case_data: dict) -> str: + """ + 获取用例的 host + :return: + """ + try: + _url = case_data['url'] + _host = case_data['host'] + if _url is None or _host is None: + raise ValueError(f"用例中的 url 或者 host 不能为空!\n 用例ID: {case_id} \n 用例路径: {self.filePath}") + else: + return _host + _url + except KeyError: + raise KeyError(f"用例中未找到 host或url. 用例ID: {case_id}") + + def get_case_method(self, case_id: str, case_data: dict) -> str: + """ + 获取用例的请求方式:GET/POST/PUT/DELETE + :return: + """ + try: + _case_method = case_data['method'] + _request_method = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTION'] + if _case_method.upper() in _request_method: + return _case_method.upper() + else: + raise ValueError(f"method 目前只支持 {_request_method} 请求方式,如需新增请联系管理员. " + f"{self.raise_value_error(data_name='请求方式', case_id=case_id, detail=_case_method)}") + + except AttributeError: + raise ValueError(f"method 目前只支持 { ['GET', 'POST', 'PUT', 'DELETE', 'uplpad_file_test', 'HEAD', 'OPTION']} 请求方式," + f"如需新增请联系管理员! " + f"{self.raise_value_error(data_name='请求方式', case_id=case_id, detail=case_data['method'])}") + except KeyError: + raise KeyError(f"用例中未找到请求方式 method. 用例ID: {case_id}") + + @classmethod + def get_case_detail(cls, case_data: dict) -> str: + """ + 获取用例描述 + :return: + """ + try: + return case_data['detail'] + except KeyError: + raise KeyError(f"用例中未找到用例描述 detail. 用例ID: {case_data['detail']}") + + @classmethod + def get_headers(cls, case_id: str, case_data: dict) -> dict: + """ + 胡求用例请求头中的信息 + :return: + """ + try: + _header = case_data['headers'] + return _header + except KeyError: + raise KeyError(f"用例中未找到请求头 headers. 用例ID: {case_id}") + + def raise_value_error(self, data_name: str, case_id: str, detail: [str, list, dict]): + """ + 所有用例填写不规范的异常提示 + :param data_name: 参数名称 + :param case_id: 用例ID + :param detail: 参数内容 + :return: + """ + detail = f"用例中的 {data_name} 填写不正确!\n 用例ID: {case_id} \n 用例路径: {self.filePath}\n" \ + f"当前填写的内容: {detail}" + + return detail + + def get_request_type(self, case_id: str, case_data: dict) -> str: + """ + 获取请求类型,params、data、json + :return: + """ + + _types = ['JSON', 'PARAMS', 'FILE', 'DATE'] + + try: + _request_type = case_data['requestType'] + # 判断用户填写的 requestType是否符合规范 + if _request_type.upper() in _types: + return _request_type.upper() + else: + raise ValueError(self.raise_value_error(data_name='requestType', case_id=case_id, detail=_request_type)) + # 异常捕捉 + except AttributeError: + raise ValueError(self.raise_value_error(data_name='requestType', + case_id=case_id, detail=case_data['requestType'])) + except KeyError: + raise KeyError(f"用例中未找到 requestType. 用例ID: {case_id}") + + @classmethod + def get_is_run(cls, case_id: str, case_data: dict) -> str: + """ + 获取执行状态, 为 true 或者 None 都会执行 + :return: + """ + try: + return case_data['is_run'] + except KeyError: + raise KeyError(f"用例中未找到 is_run. 用例ID: {case_id}") + + @classmethod + def get_dependence_case(cls, case_id: str, case_data: dict) -> dict: + """ + 获取是否依赖的用例 + :return: + """ + try: + _dependence_case = case_data['dependence_case'] + return _dependence_case + except KeyError: + raise KeyError(f"用例中未找到 dependence_case. 用例ID: {case_id}") + + @classmethod + def get_dependence_case_data(cls, case_id: str, case_data: dict) -> str: + """ + 获取依赖的用例 + :return: + """ + try: + _dependence_case_data = case_data['dependence_case_data'] + return _dependence_case_data + except KeyError: + raise KeyError(f"用例中未找到 dependence_case. 用例ID: {case_id}") + + @classmethod + def get_case_dates(cls, case_id: str, case_data: dict) -> dict: + """ + 获取请求数据 + :param case_id: + :param case_data: + :return: + """ + try: + _dates = case_data['data'] + return _dates + except KeyError: + raise KeyError(f"用例中未找到 data 参数. 用例ID: {case_id}") + + def get_assert(self, case_id: str, case_data: dict): + """ + 获取需要断言的数据 + :return: + """ + try: + _assert = case_data['assert'] + if _assert is None: + raise self.raise_value_error(data_name="assert", case_id=case_id, detail=_assert) + return case_data['assert'] + except KeyError: + raise KeyError(f"用例中未找到 assert 参数. 用例ID: {case_id}") + + @classmethod + def get_sql(cls, case_id: str, case_data: dict): + """ + 获取测试用例中的sql + :return: + """ + try: + _sql = case_data['sql'] + # 判断数据库开关为开启状态,并且sql不为空 + if sql_switch() and _sql is not None: + return case_data['sql'] + else: + return None + except KeyError: + raise KeyError(f"用例中未找到 sql 参数. 用例ID: {case_id}") + + +if __name__ == '__main__': + data = CaseData(r'C:\Users\hzxy\PycharmProjects\pyestAutoApi\data\WorkApplyCenter\work_apply_good_detail.yaml').case_process() + print(data) \ No newline at end of file diff --git a/tools/regularControl.py b/utils/readFilesUtils/regularControl.py similarity index 86% rename from tools/regularControl.py rename to utils/readFilesUtils/regularControl.py index 99c9fb0..b2690f4 100644 --- a/tools/regularControl.py +++ b/utils/readFilesUtils/regularControl.py @@ -1,12 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/26 0:11 +# @Time : 2022/3/28 10:52 # @Author : 余少琪 + import re -from faker import Faker -from tools.logControl import ERROR import datetime import jsonpath +from faker import Faker +from utils.logUtils.logControl import ERROR class Context: @@ -58,15 +59,6 @@ class Context: email = self.f.email() return email - @property - def merchant_self_operated_shop(self) -> int: - """ - - :return: 商家端自营店铺ID - """ - self_operated_shop = 515 - return self_operated_shop - @property def get_time(self) -> datetime.datetime: """ @@ -78,16 +70,16 @@ class Context: @property def host(self) -> str: - from tools.yamlControl import GetYamlData + from utils.readFilesUtils.yamlControl import GetYamlData from config.setting import ConfigHandler # 从配置文件conf.yaml 文件中获取到域名,然后使用正则替换 host = GetYamlData(ConfigHandler.config_path) \ - .get_yaml_data()['Host'] + .get_yaml_data()['host'] return host -def regular(target) -> str: +def regular(target): """ 使用正则替换请求数据 :return: @@ -122,7 +114,7 @@ def sql_regular(value, res=None): pattern = re.compile(r'\$json\(' + i.replace('$', "\$").replace('[', '\[') + r'\)\$') key = str(sql_json(i, res)) value = re.sub(pattern, key, value, count=1) - value = sql_regular(value, res) + value = sql_json_list(value, res) return value diff --git a/tools/yamlControl.py b/utils/readFilesUtils/yamlControl.py similarity index 77% rename from tools/yamlControl.py rename to utils/readFilesUtils/yamlControl.py index a056cf0..9412e18 100644 --- a/tools/yamlControl.py +++ b/utils/readFilesUtils/yamlControl.py @@ -1,10 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/24 22:08 +# @Time : 2022/3/28 10:51 # @Author : 余少琪 -import yaml.scanner + import os -from tools.regularControl import regular +import yaml.scanner +from utils.readFilesUtils.regularControl import regular class GetYamlData: @@ -21,8 +22,12 @@ class GetYamlData: # 判断文件是否存在 if os.path.exists(self.fileDir): data = open(self.fileDir, 'r', encoding='utf-8') - res = yaml.load(data, Loader=yaml.FullLoader) - return res + try: + res = yaml.load(data, Loader=yaml.FullLoader) + return res + except UnicodeDecodeError: + raise ValueError(f"yaml文件编码错误,文件路径:{self.fileDir}") + else: raise FileNotFoundError("文件路径不存在") @@ -73,14 +78,12 @@ class GetCaseData(GetYamlData): 获取测试用例数据, 转换成指定数据格式 :return: """ - try: - res_list = [] - for i in self.get_yaml_data(): - # 正则替换相关数据 - re_data = regular(str(i)) - re_data = eval(re_data) - res_list.append(re_data) - return res_list + try: + _yaml_data = self.get_yaml_data() + # 正则处理yaml文件中的数据 + re_data = regular(str(_yaml_data)) + return eval(re_data) + except yaml.scanner.ScannerError: - raise ValueError("yaml格式不正确") + raise yaml.scanner.ScannerError("yaml格式不正确") diff --git a/utils/recordingUtils/__init__.py b/utils/recordingUtils/__init__.py new file mode 100644 index 0000000..a22d3ab --- /dev/null +++ b/utils/recordingUtils/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 15:46 +# @Author : 余少琪 diff --git a/utils/recordingUtils/mitmproxyContorl.py b/utils/recordingUtils/mitmproxyContorl.py new file mode 100644 index 0000000..30db2d4 --- /dev/null +++ b/utils/recordingUtils/mitmproxyContorl.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 15:46 +# @Author : 余少琪 + +import mitmproxy.http +from mitmproxy import ctx +from ruamel import yaml +import os +from typing import Any, Union +from urllib.parse import parse_qs, urlparse + + +class Counter: + """ + 代理录制,基于 mitmproxy 库拦截获取网络请求 + 将接口请求数据转换成 yaml 测试用例 + 参考资料: https://blog.wolfogre.com/posts/usage-of-mitmproxy/ + """ + + def __init__(self, filter_url: list, filename: str = './data/proxy_data.yaml'): + self.num = 0 + self.file = filename + self.counter = 1 + # 需要过滤的 url + self.url = filter_url + + def response(self, flow: mitmproxy.http.HTTPFlow) -> None: + """ + mitmproxy抓包处理响应,在这里汇总需要数据, 过滤 包含指定url,并且响应格式是 json的 + :param flow: + :return: + """ + # 存放需要过滤的接口 + filter_url_type = ['.css', '.js', '.map', '.ico', '.png', '.woff', '.map3', '.jpeg'] + url = flow.request.url + # 判断过滤掉含 filter_url_type 中后缀的 url + if any(i in url for i in filter_url_type) is False: + # 存放测试用例 + if self.filter_url(url): + + data = self.data_handle(flow.request.text) + method = flow.request.method + header = self.token_handle(flow.request.headers) + response = flow.response.text + case_id = self.get_case_id(url) + str(self.counter) + cases = { + case_id: { + "host": self.host_handle(url, types='host'), + "url": self.host_handle(url), + "method": method, + "detail": None, + "headers": header, + 'requestType': self.request_type_handler(method), + "is_run": True, + "data": data, + "dependence_case": None, + "dependence_case_data": None, + "assert": self.response_code_handler(response), + "sql": None + } + + } + # 判断如果请求参数时拼接在url中,提取url中参数,转换成字典 + if "?" in url: + cases[case_id]['url'] = self.get_url_handler(url)[1] + cases[case_id]['data'] = self.get_url_handler(url)[0] + + # 处理请求头中需要的数据 + self.request_headers(flow.request.headers, cases) + + ctx.log.info("=" * 100) + ctx.log.info(cases) + + # 判断文件不存在则创建文件 + try: + self.yaml_cases(cases) + except FileNotFoundError: + os.makedirs(self.file) + self.counter += 1 + + @classmethod + def get_case_id(cls, url: str) -> str: + """ + 通过url,提取对应的user_id + :param url: + :return: + """ + _url_path = str(url).split('?')[0] + # 通过url中的接口地址,最后一个参数,作为case_id的名称 + _url = _url_path.split('/') + return _url[-1] + + def filter_url(self, url: str) -> bool: + """过滤url""" + for i in self.url: + if i in url: + return True + return False + + @classmethod + def response_code_handler(cls, response) -> Union[dict, None]: + # 处理接口响应,默认断言数据为code码,如果接口没有code码,则返回None + try: + data = cls.data_handle(response) + return {"code": {"jsonpath": "$.code", "type": "==", + "value": data['code'], "AssertType": None}} + except KeyError: + return None + except NameError: + return None + + @classmethod + def request_type_handler(cls, method: str) -> str: + # 处理请求类型,有params、json、file,需要根据公司的业务情况自己调整 + if method == 'GET': + # 如我们公司只有get请求是prams,其他都是json的 + return 'params' + else: + return 'json' + + @classmethod + def request_headers(cls, headers, cases: dict) -> dict: + # 公司业务: 请求头中包含了 X-Shop-Id、X-Sub-Biz-Type, 其他项目可注释此段代码 + if 'X-Shop-Id' in headers: + cases['headers']['X-Shop-Id'] = headers['X-Shop-Id'] + if 'X-Biz-Type' in headers: + cases['headers']['X-Biz-Type'] = headers['X-Biz-Type'] + if 'X-Sub-Biz-Type' in headers: + cases['headers']['X-Sub-Biz-Type'] = headers['X-Sub-Biz-Type'] + return cases + + @classmethod + def data_handle(cls, dict_str) -> Any: + # 处理接口请求、响应的数据,如null、true格式问题 + try: + if dict_str != "": + if 'null' in dict_str: + dict_str = dict_str.replace('null', 'None') + if 'true' in dict_str: + dict_str = dict_str.replace('true', 'True') + if 'false' in dict_str: + dict_str = dict_str.replace('false', 'False') + dict_str = eval(dict_str) + if dict_str == "": + dict_str = None + return dict_str + except Exception: + raise + + @classmethod + def token_handle(cls, header) -> dict: + # token 处理 + headers = {} + if 'token' in header: + headers['token'] = header['token'] + # Content-Type + headers['Content-Type'] = header['Content-Type'] + return headers + + def host_handle(self, url: str, types='url') -> str: + """ + 解析 url + :param types: 获取类型: url、host + :param url: https://xxxx.test.xxxx.com/#/goods/listShop + :return: 最终返回 ${{MerchantHost}}/#/goods/listShop + """ + for i in self.url: + host = None + if "merchant.test.feng-go.com" in i: + host = "${{MerchantHost}}" + elif "cms.test.hunshehui.cn" in i: + host = "${{CMSHost}}" + elif "work.test.feng-go.com" in i: + host = "${{WorkHost}}" + if types == 'host': + # 返回域名 + return host + elif types == 'url': + # 返回接口地址 + return url.split(i)[-1] + + def yaml_cases(self, data: dict) -> None: + """ + 写入 yaml 数据 + :param data: 测试用例数据 + :return: + """ + with open(self.file, "a", encoding="utf-8") as f: + yaml.dump(data, f, Dumper=yaml.RoundTripDumper, allow_unicode=True) + + @classmethod + def get_url_handler(cls, url: str) -> tuple: + """ + 将 url 中的参数 转换成字典 + :param url: /trade?tradeNo=&outTradeId=11 + :return: {“outTradeId”: 11} + """ + query = urlparse(url).query + # 将字符串转换为字典 + params = parse_qs(query) + # 所得的字典的value都是以列表的形式存在,如请求url中的参数值为空,则字典中不会有该参数 + result = {key: params[key][0] for key in params} + url = url[0:url.rfind('?')] + return result, url + + +# 1、本机需要设置代理,默认端口为: 8080 +# 2、控制台输入 mitmweb -s .\utils\recordingUtils\mitmproxyControl.py - p 8888命令开启代理模式进行录制 + + +addons = [ + Counter(["http://work.test.feng-go.com", "http://cms.test.hunshehui.cn/"]) +] diff --git a/utils/requestsUtils/__pycache__/dependentCase.cpython-39.pyc b/utils/requestsUtils/__pycache__/dependentCase.cpython-39.pyc new file mode 100644 index 0000000..61811ad Binary files /dev/null and b/utils/requestsUtils/__pycache__/dependentCase.cpython-39.pyc differ diff --git a/utils/requestsUtils/__pycache__/requestControl.cpython-39.pyc b/utils/requestsUtils/__pycache__/requestControl.cpython-39.pyc new file mode 100644 index 0000000..56d5663 Binary files /dev/null and b/utils/requestsUtils/__pycache__/requestControl.cpython-39.pyc differ diff --git a/utils/requestsUtils/dependentCase.py b/utils/requestsUtils/dependentCase.py new file mode 100644 index 0000000..de10a09 --- /dev/null +++ b/utils/requestsUtils/dependentCase.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 16:08 +# @Author : 余少琪 + +from jsonpath import jsonpath +from utils.cacheUtils.cacheControl import Cache +from utils.requestsUtils.requestControl import RequestControl +from Enums.dependentType_enum import DependentType +from Enums.yamlData_enum import YAMLDate + + +class DependentCase: + + @classmethod + def get_cache(cls, case_id: str) -> str: + """ + 获取缓存用例池中的数据,通过 case_id 提取 + :param case_id: + :return: case_id_01 + """ + _case_data = eval(Cache('case_process').get_cache())[case_id] + return _case_data + + @classmethod + def jsonpath_data(cls, obj: dict, expr: str) -> list: + """ + 通过jsonpath提取依赖的数据 + :param obj: 对象信息 + :param expr: jsonpath 方法 + :return: 提取到的内容值,返回是个数组 + + 对象: {"data": applyID} --> jsonpath提取方法: $.data.data.[0].applyId + """ + + _jsonpath_data = jsonpath(obj, expr) + # 判断是否正常提取到数据,如未提取到,则抛异常 + if _jsonpath_data is not False: + return _jsonpath_data + else: + raise ValueError(f"jsonpath提取失败!\n 提取的数据: {obj} \n jsonpath规则: {expr}") + + @classmethod + def url_replace(cls, replace_key: str, jsonpath_dates: dict, jsonpath_data: list, case_data: dict): + """ + url中的动态参数替换 + :param jsonpath_data: jsonpath 解析出来的数据值 + :param replace_key: 用例中需要替换数据的 replace_key + :param jsonpath_dates: jsonpath 存放的数据值 + :param case_data: 用例数据 + :return: + """ + + # 如: 一般有些接口的参数在url中,并且没有参数名称, /api/v1/work/spu/approval/spuApplyDetails/{id} + # 那么可以使用如下方式编写用例, 可以使用 $url_params{}替换, + # 如/api/v1/work/spu/approval/spuApplyDetails/$url_params{id} + + if "$url_param" in replace_key: + _url = case_data['url'].replace(replace_key, str(jsonpath_data[0])) + jsonpath_dates['$.url'] = _url + else: + jsonpath_dates[replace_key] = jsonpath_data[0] + + @classmethod + def is_dependent(cls, case_data: dict) -> [list, bool]: + """ + 判断是否有数据依赖 + :return: + """ + + _dependent_type = case_data[YAMLDate.DEPENDENCE_CASE.value] + # 判断是否有依赖 + if _dependent_type is True: + # 读取依赖相关的用例数据 + _dependence_case_dates = case_data[YAMLDate.DEPENDENCE_CASE_DATA.value] + jsonpath_dates = {} + # 循环所有需要依赖的数据 + for dependence_case_data in _dependence_case_dates: + dependent_data = dependence_case_data['dependent_data'] + for i in dependent_data: + + _case_id = dependence_case_data[YAMLDate.CASE_ID.value] + _jsonpath = i[YAMLDate.JSONPATH.value] + _request_data = case_data[YAMLDate.DATA.value] + _replace_key = i[YAMLDate.REPLACE_KEY.value] + + # 判断依赖数据类型, 依赖 response 中的数据 + if i[YAMLDate.DEPENDENT_TYPE.value] == DependentType.RESPONSE.value: + res = RequestControl().http_request(cls.get_cache(_case_id)) + jsonpath_data = cls.jsonpath_data(res[0], _jsonpath) + cls.url_replace(replace_key=_replace_key, jsonpath_dates=jsonpath_dates, + jsonpath_data=jsonpath_data, case_data=case_data) + + # 判断依赖数据类型, 依赖 request 中的数据 + elif i[YAMLDate.DEPENDENT_TYPE.value] == DependentType.REQUEST.value: + jsonpath_data = cls.jsonpath_data(case_data, _jsonpath) + jsonpath_dates[_replace_key] = jsonpath_data[0] + cls.url_replace(replace_key=_replace_key, jsonpath_dates=jsonpath_dates, + jsonpath_data=jsonpath_data, case_data=case_data) + + # 判断依赖数据类型,依赖 sql中的数据 + elif i[YAMLDate.DEPENDENT_TYPE.value] == DependentType.SQL_DATA.value: + res = RequestControl().http_request(cls.get_cache(_case_id)) + jsonpath_data = cls.jsonpath_data(res[1], _jsonpath) + jsonpath_dates[_replace_key] = jsonpath_data[0] + cls.url_replace(replace_key=_replace_key, jsonpath_dates=jsonpath_dates, + jsonpath_data=jsonpath_data, case_data=case_data) + return jsonpath_dates + else: + return False + + @classmethod + def get_dependent_data(cls, yaml_data: dict) -> None: + """ + jsonpath 和 依赖的数据,进行替换 + :param yaml_data: + :return: + """ + _dependent_data = DependentCase().is_dependent(yaml_data) + # 判断有依赖 + if _dependent_data is not False: + for key, value in _dependent_data.items(): + # 通过jsonpath判断出需要替换数据的位置 + _change_data = key.split(".") + # jsonpath 数据解析 + _new_data = 'yaml_data' + '' + for i in _change_data: + if i == '$': + pass + elif i[0] == '[' and i[-1] == ']': + _new_data += "[" + i[1:-1] + "]" + else: + _new_data += "[" + "'" + i + "'" + "]" + # 最终提取到的数据,转换成 yaml_data[xxx][xxx] + _new_data += ' = value' + exec(_new_data) \ No newline at end of file diff --git a/utils/requestsUtils/requestControl.py b/utils/requestsUtils/requestControl.py new file mode 100644 index 0000000..abc2dcb --- /dev/null +++ b/utils/requestsUtils/requestControl.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 12:52 +# @Author : 余少琪 + +import random +import allure +import requests +from typing import Any +from utils import sql_switch +from requests_toolbelt import MultipartEncoder +from utils.logUtils.logDecoratorl import log_decorator +from utils.mysqlUtils.mysqlControl import MysqlDB +from Enums.requestType_enum import RequestType +from Enums.yamlData_enum import YAMLDate +from config.setting import ConfigHandler +from utils.cacheUtils.cacheControl import Cache +from utils.otherUtils.allureDate.allure_tools import allure_step, allure_step_no, allure_attach + + +class RequestControl: + """ 封装请求 """ + + @classmethod + def _check_params(cls, response, yaml_data) -> Any: + """ 抽离出通用模块,判断request中的一些参数校验 """ + # 判断响应码不等于200时,打印文本格式信息 + if response.status_code != 200: + return response.text, {"sql": None}, yaml_data + # 判断 sql 不是空的话,获取数据库的数据,并且返回 + if sql_switch() and yaml_data['sql'] is not None: + sql_data = MysqlDB().assert_execution(sql=yaml_data['sql'], resp=response.json()) + return response.json(), sql_data, yaml_data + return response.json(), {"sql": None}, yaml_data + + @classmethod + def case_token(cls, header) -> None: + try: + # 判断用例是否依赖token + _token = header['token'] + # 如果依赖则从缓存中读取对应得token信息 + try: + # 判断如果没有缓存数据,则直接取用例中的数据 + cache = Cache(_token).get_cache() + header['token'] = cache + except FileNotFoundError: + pass + except KeyError: + pass + + @classmethod + def upload_file(cls, yaml_data): + # 处理上传多个文件的情况 + _files = [] + file_data = {} + for key, value in yaml_data[YAMLDate.DATA.value]['file'].items(): + file_path = ConfigHandler.file_path + value + file_data[key] = (value, open(file_path, 'rb'), 'application/octet-stream') + _files.append(file_data) + # allure中展示该附件 + allure_attach(source=file_path, name=value, extension=value) + # 兼容就要上传文件,又要上传其他类型参数 + try: + for key, value in yaml_data[YAMLDate.DATA.value]['data'].items(): + file_data[key] = value + except KeyError: + pass + + multipart = MultipartEncoder( + fields=file_data, # 字典格式 + boundary='-----------------------------' + str(random.randint(int(1e28), int(1e29 - 1))) + ) + + yaml_data[YAMLDate.HEADER.value]['Content-Type'] = multipart.content_type + + try: + params = yaml_data[YAMLDate.DATA.value]['params'] + except KeyError: + params = None + return multipart, params + + from utils.logUtils.runTimeDecoratorl import execution_duration + @classmethod + @log_decorator(True) + @execution_duration(2000) + def http_request(cls, yaml_data, **kwargs): + from utils.requestsUtils.dependentCase import DependentCase + _is_run = yaml_data[YAMLDate.IS_RUN.value] + _method = yaml_data[YAMLDate.METHOD.value] + _detail = yaml_data[YAMLDate.DETAIL.value] + _headers = yaml_data[YAMLDate.HEADER.value] + _requestType = yaml_data[YAMLDate.REQUEST_TYPE.value].upper() + _data = yaml_data[YAMLDate.DATA.value] + _sql = yaml_data[YAMLDate.SQL.value] + _assert = yaml_data[YAMLDate.ASSERT.value] + _dependent_data = yaml_data[YAMLDate.DEPENDENCE_CASE_DATA.value] + cls.case_token(_headers) + res = None + + # 判断用例是否执行 + if _is_run is True or _is_run is None: + # 处理多业务逻辑 + DependentCase().get_dependent_data(yaml_data) + + if _requestType == RequestType.JSON.value: + res = requests.request(method=_method, url=yaml_data[YAMLDate.URL.value], json=_data, + headers=_headers, **kwargs) + elif _requestType == RequestType.PARAMS.value: + + res = requests.request(method=_method, url=yaml_data[YAMLDate.URL.value], json=_data, headers=_headers, + **kwargs) + elif _requestType == RequestType.PARAMS.value: + res = requests.request(method=_method, url=yaml_data[YAMLDate.URL.value], params=_data, + headers=_headers, **kwargs) + # 判断上传文件 + elif _requestType == RequestType.FILE.value: + multipart = cls.upload_file(yaml_data) + res = requests.request(method=_method, url=yaml_data[YAMLDate.URL.value], + data=multipart[0], params=multipart[1], headers=_headers, **kwargs) + + elif _requestType == RequestType.DATE.value: + + res = requests.request(method=_method, url=yaml_data[YAMLDate.URL.value], data=_data, + headers=_headers, **kwargs) + + elif _requestType == RequestType.DATE.value: + res = requests.request(method=_method, url=yaml_data[YAMLDate.URL.value], data=_data, headers=_headers, + **kwargs) + allure.dynamic.title(_detail) + allure_step_no(f"请求URL: {yaml_data[YAMLDate.URL.value]}") + allure_step_no(f"请求方式: {_method}") + allure_step("请求头: ", _headers) + allure_step("请求数据: ", _data) + allure_step("依赖数据: ", _dependent_data) + allure_step("预期数据: ", _assert) + allure_step_no(f"响应耗时(s): {res.elapsed.total_seconds()}") + if res.status_code != 200: + allure_step("响应结果: ", res.text) + else: + allure_step("响应结果: ", res.json()) + return cls._check_params(res, yaml_data) + else: + # 用例跳过执行的话,所有数据都返回 False + return False, False, yaml_data diff --git a/utils/timesUtils/__init__.py b/utils/timesUtils/__init__.py new file mode 100644 index 0000000..199fa90 --- /dev/null +++ b/utils/timesUtils/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# @Time : 2022/3/28 15:47 +# @Author : 余少琪 diff --git a/utils/timesUtils/__pycache__/__init__.cpython-39.pyc b/utils/timesUtils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..7d3703c Binary files /dev/null and b/utils/timesUtils/__pycache__/__init__.cpython-39.pyc differ diff --git a/utils/timesUtils/__pycache__/timeControl.cpython-39.pyc b/utils/timesUtils/__pycache__/timeControl.cpython-39.pyc new file mode 100644 index 0000000..081f50e Binary files /dev/null and b/utils/timesUtils/__pycache__/timeControl.cpython-39.pyc differ diff --git a/tools/gettimeControl.py b/utils/timesUtils/timeControl.py similarity index 54% rename from tools/gettimeControl.py rename to utils/timesUtils/timeControl.py index 6a10251..12d7404 100644 --- a/tools/gettimeControl.py +++ b/utils/timesUtils/timeControl.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# @Time : 2021/11/25 23:24 +# @Time : 2022/3/28 15:47 # @Author : 余少琪 import time from datetime import datetime -def count_milliseconds(): +def countMilliseconds(): """ 计算时间 :return: @@ -18,38 +18,38 @@ def count_milliseconds(): return access_delta -def timestamp_conversion(time_str: str) -> int: +def Timestamp_conversion(timeStr: str) -> int: """ 时间戳转换,将日期格式转换成时间戳 - :param time_str: 时间 + :param timeStr: 时间 :return: """ try: - datetime_format = datetime.strptime(str(time_str), "%Y-%m-%d %H:%M:%S") - timestamp = int(time.mktime(datetime_format.timetuple()) * 1000.0 + datetime_format.microsecond / 1000.0) + datetimeFormat = datetime.strptime(str(timeStr), "%Y-%m-%d %H:%M:%S") + timestamp = int(time.mktime(datetimeFormat.timetuple()) * 1000.0 + datetimeFormat.microsecond / 1000.0) return timestamp except ValueError: - raise ValueError('日期格式错误, 需要传入得格式为 "%Y-%m-%d %H:%M:%S" ') + raise '日期格式错误, 需要传入得格式为 "%Y-%m-%d %H:%M:%S" ' -def time_conversion(time_num: int): +def Time_conversion(timeNum: int): """ 时间戳转换成日期 - :param time_num: + :param timeNum: :return: """ - if isinstance(time_num, int): - time_stamp = float(time_num / 1000) - time_array = time.localtime(time_stamp) - other_style_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array) - return other_style_time + if isinstance(timeNum, int): + timeStamp = float(timeNum / 1000) + timeArray = time.localtime(timeStamp) + otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray) + return otherStyleTime else: - raise ValueError("请传入正确的时间戳") + raise "请传入正确的时间戳" -def now_time() -> str: +def NowTime(): """ 获取当前时间, 日期格式: 2021-12-11 12:39:25 :return: @@ -74,7 +74,3 @@ def get_now_time() -> int: """ return int(time.time()) * 1000 - -if __name__ == '__main__': - print(now_time()) - time_conversion(1547450538000)