# UnitTestApiAutoTest **Repository Path**: y_n_y/autotestproject ## Basic Information - **Project Name**: UnitTestApiAutoTest - **Description**: UnitTest+UnitTestReport+JsonPath+Requests+logging等实现的一套接口自动化测试工具,支持JsonPaht或正则断言、接口间数据依赖、测试数据隔离、测试用例失败重运行、轮询接口重试、惰性校验、邮件或钉钉通知、测试报告生成。 - **Primary Language**: Python - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: https://gitee.com/y_n_y/autotestproject - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2022-10-11 - **Last Updated**: 2022-10-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: Python, 接口自动化, unittest, Requests ## README ![](https://img1.baidu.com/it/u=3212346217,2233525104&fm=253&fmt=auto&app=138&f=JPEG) ## 简介 > 使用`Python`语言 + `Python`第三方库实现的接口自动化测试工具,使用该工具 Python版本 >= 3.7 ## 实现功能 `Python` + `UnitTest` + `UnitTestReport` + `JsonPath` + `logging`,支持以下功能: - 测试数据隔离 - 接口间数据依赖 - 测试用例失败重运行 - 轮询接口重试 - `JsonPath`或正则断言 - 惰性校验 - 日志采集 - 邮件或钉钉通知 - 测试报告生成 ## 目录结构 ``` ├─common \\公共方法 │ │ common.py \\测试管理 │ │ ddt.py \\数据驱动 1 │ ├─data \\测试用例 │ login_test.yaml ├─logs \\日志存储(默认被git忽略) │ ├─report \\测试报告存储(默认被git忽略) │ ├─settings \\路径读取 │ │ setting.py │ ├─testcase \\用例执行 │ │ testcase.py │ ├─utils \\工具类 │ ├─config \\读取config.ini文件 │ │ │ config.py │ ├─request \\请求模块 │ │ │ request.py │ ├─log \\日志模块 │ │ │ log.py | ├─.gitignore \\项目git忽略文件 ├─config.ini \\配置文件 ├─debugtalk.py \\用户自定义函数 ├─LICENSE \\开源MIT协议 ├─main.py \\Python启动文件 ├─README.MD \\项目简介 ├─requirements.txt \\项目依赖库文件 ├─采坑记录 \\问题记录 ``` ## 依赖库 ``` jsonpath==0.82 retry==0.9.2 unittestreport==1.5.1 requests~=2.24.0 assertpy~=1.1 colorlog~=6.7.0 ``` ## 框架逻辑 https://boardmix.cn/app/editor/ytYA_5P6k7diz3vIkBTN3g ## 用例模型 ```yaml - id: 1 name: login describe: 登录 request: url: user/login method: post data: username: yjc11 password: 123456 extract: username: $..username cookie: $.Set-Cookie validate: status_code: 200 errorCode: actual: $.errorCode expect: 0 compare: == username: actual: $..username expect: ${1-username} compare: == ``` ### case 模型 | 属性名 | 默认值 | 可选值 | 是否必填 | 类型 | 注释 | | -------- | ------ | ---------- | -------- | ---- | ------------------------------ | | id | | | 是 | int | 用例ID | | name | | | 是 | str | 用例名称 | | describe | | | 是 | str | 用例描述 | | skip | | true/false | 否 | bool | 是否跳过 | | retry | | | 否 | dict | 接口轮询使用,参考retry模型 | | request | | | 是 | dict | 发送请求,参考request模型 | | extract | | | 否 | dict | 提取动态参数实现上下游接口依赖 | | validate | | | 是 | dict | 校验,参考validate模型 | ### retry 模型 | 属性名 | 默认值 | 可选值 | 是否必填 | 类型 | 注释 | | ------ | ------ | ------ | -------- | ---- | ---------------------------- | | tries | | | 是 | int | 最大重试次数 | | delay | | | 是 | int | 每次重试的时间间隔(单位:秒) | ### request 模型 | 属性名 | 默认值 | 可选值 | 是否必填 | 类型 | 注释 | | ------- | ------ | ------------------------ | -------- | ---- | ------------------------------------------------------------ | | url | | | 是 | str | 请求path | | method | | GET、POST、DELETE、PUT等 | 是 | str | 请求方法 | | headers | | | 否 | dict | 请求头 | | cookies | | | 否 | dict | 请求cookie | | params | | | 否 | dict | GET请求url?后的拼接参数 | | data | | | 否 | dict | 请求数据(适用Content-Type: application/x-www-form-urlencoded) | | json | | | 否 | dict | 请求数据(适用Content-Type: application/json) | ### validate 模型 | 属性名 | 默认值 | 可选值 | 是否必填 | 类型 | 注释 | | ----------- | ------ | ------ | -------- | ---- | -------------- | | status_code | | | 是 | int | HTTP响应状态码 | ## 惰性校验 采用`assertpy`第三方库去实现,具体使用请参考 **[assertpy](https://gitee.com/kuailel/assertpy)** 官方文档。 通常,断言失败会引发错误,从而立即停止测试执行。软断言是一种将断言失败收集在一起的方法,可以在结束时立即引发,而不会停止测试。要在`assertpy`中使用软断言,只需使用`with soft_assertions()`上下文管理器,如下所示: ```python from assertpy import assert_that, soft_assertions with soft_assertions(): assert_that('foo').is_length(4) assert_that('foo').is_empty() assert_that('foo').is_false() assert_that('foo').is_digit() assert_that('123').is_alpha() assert_that('foo').is_upper() assert_that('FOO').is_lower() assert_that('foo').is_equal_to('bar') assert_that('foo').is_not_equal_to('foo') assert_that('foo').is_equal_to_ignoring_case('BAR') ``` 在块的末尾,所有断言失败都被收集在一起,并引发一个`AssertionError`: ```shell AssertionError: soft assertion failures: 1. Expected to be of length <4>, but was <3>. 2. Expected to be empty string, but was not. 3. Expected , but was not. 4. Expected to contain only digits, but did not. 5. Expected <123> to contain only alphabetic chars, but did not. 6. Expected to contain only uppercase chars, but did not. 7. Expected to contain only lowercase chars, but did not. 8. Expected to be equal to , but was not. 9. Expected to be not equal to , but was. 10. Expected to be case-insensitive equal to , but was not. ``` ## 测试报告 测试报告这里采用 **[unittestreport](https://unittestreport.readthedocs.io/en/latest/)** 第三方库去实现,该库已实现了如下功能: - HTML测试报告生成 - unittest数据驱动 - 测试用例失败重运行 - 多线程并发执行用例 - 发送测试结果及报告到邮箱 - 测试结果推送到钉钉 - 测试结果推送到企业微信 ```python import time from unittestreport import TestRunner, Load from settings import * # 1.加载用例到测试套件 suites = Load.discover(TEST_PATH, pattern='test*.py') # 自动化测试报告名称 report_name = time.strftime("%Y%m%d_%H%M%S") + "_" + "测试报告.html" # 2.创建一个用例运行程序 runner = TestRunner(suites, filename=report_name, report_dir=REPORT_PATH, title='测试报告', tester='叶鸟翼', desc="接口自动化测试报告", templates=2) # 3.运行测试用例 runner.run() ``` 在使用`TestRunner`创建测试运行程序时,可以通过以下参数来,自定义报告的相关内容 - `suites`: 测试套件(必传) - `filename`: 指定报告文件名 - `report_dir`: 指定存放报告路径 - `title`: 指定测试报告的标题 - `templates`: 可以指定1,2,3三个风格的模板 - `tester`: 测试人员名称 **报告样式一**: ![](https://unittestreport.readthedocs.io/en/latest/img/1615966527547.png) **报告样式二**: ![](https://unittestreport.readthedocs.io/en/latest/img/report1.jpg) **报告样式三**: ![](https://unittestreport.readthedocs.io/en/latest/img/report3.jpg) ## 收到的邮件样式 ![](https://unittestreport.readthedocs.io/en/latest/img/1620456241096.png)