接口测试 yamlpy 接口测试框架

此生不换 · 2020年02月23日 · 最后由 此生不换 回复于 2021年12月06日 · 2610 次阅读

yamlpy

yamlpy 接口测试框架

工程主页

readthedocs:

https://yamlpy-docs.readthedocs.io/zh_CN/latest/

pypi:

https://pypi.org/project/yamlpy/

github:

https://github.com/yjlch1016/yamlpy

yamlpy 即为 yaml 文件 +pytest 单元测试框架的缩写

可看作是一个脚手架工具

可快速生成项目的各个目录与文件

支持 MySQL、PgSQL 与 MongoDB 等数据库的增删改查

支持 Jenkins、Docker 等 CI/CD 工具

支持飞书、钉钉、企业微信等机器人

只需维护一份或者多份 yaml(或者 json)文件即可

yamlapi 接口测试框架对比,

整体结构仍然保持不变,

yaml 文件(或者 json 文件)格式仍然保持不变,

可以通用,

抛弃了 python 自带的 unittest 单元测试框架、ddt 数据驱动第三方库、BeautifulReport 测试报告第三方库,

修改了测试类文件,

传参方式由 ddt 的@ddt.ddt@ddt.data() 改为 pytest 的@pytest.mark.parametrize(),

删掉了 tool 工具包里面的 beautiful_report_run.py 文件,

其他文件保持不变。

pip install yamlpy

安装

yamlpy -h(或yamlpy --help)

查看参数信息

yamlpy -v(或yamlpy --version)

查看版本号

pip install -U yamlpy

安装最新版

yamlpy create --p=项目名称

创建项目

例如在某个路径下执行命令:

yamlpy create --p=demo_project

yamlpy run --c=环境缩写

运行项目

例如在项目的根目录下面执行命令:

yamlpy run --c=test

yamlpy clean

清理测试报告与日志目录下的所有文件

类似于mvn clean

pip uninstall yamlpy

卸载


一、思路

1、采用 requests+PyMySQL+DBUtils+psycopg2-binary+pymongo+influxdb+demjson+loguru+
PyYAML+ruamel.yaml+pytest+pytest-html+allure-pytest+pytest-reportlog+pytest-assume+pytest-rerunfailures+pytest-instafail+pytest-sugar+pytest-timeout+pytest-parallel+tablib

2、requests 是发起 HTTP 请求的第三方库

3、PyMySQL 是连接 MySQL 的第三方库

4、DBUtils 是数据库连接池的第三方库

5、psycopg2-binary 是连接 PgSQL 的第三方库

6、pymongo 是连接 Mongo 的第三方库

7、influxdb 是连接 influxDB 的第三方库

8、demjson 是解析非标格式 json 的第三方库

9、loguru 是记录日志的第三方库

10、PyYAML 与 ruamel.yaml 是读写 yaml 文件的第三方库

11、pytest 是单元测试的第三方库

12、pytest-html 是生成 html 测试报告的插件

13、allure-pytest 是生成 allure 测试报告的插件

14、pytest-reportlog 是替换--resultlog 选项的插件

15、pytest-assume 是多重断言的插件

16、pytest-rerunfailures 是失败重跑的插件

17、pytest-instafail 是实时显示错误信息的插件

18、pytest-sugar 是显示进度的插件

19、pytest-timeout 是设置超时时间的插件

20、pytest-parallel 是多线程的插件

21、tablib 是导出多种格式数据的第三方库


二、目录结构

1、case 是测试用例包

2、report_log 是测试报告和日志的目录

3、resource 是 yaml(或者 json 文件)文件的目录

4、setting 是工程的配置文件包

5、tool 是常用方法的封装包

6、.dockerignore 是在传递给 docker 引擎时需要忽略掉的文件

7、.gitignore 是.ignore 插件需要排除的文件

8、conftest.py 是全局钩子文件

9、Dockerfile 是构建镜像的文件

10、Jenkinsfile 是 Jenkins Pipeline 文件

11、pytest.ini 是 pytest 的配置文件

12、requirements.txt 是第三方依赖库


三、yaml、json 文件说明

yaml 文件

- case_name: 用例名称
  step:
    - step_name: 步骤名称
      mysql:
        -
        -
        -
      pgsql:
        -
        -
        -
      mongo:
        -
        -
        -
      request_mode: POST
      api: /api/test
      file:
        -
        -
        -
      body:
        {"key_1":"value_1","key_2":"value_2"}
      headers:
        {"Content-Type":"application/json"}
      query_string:
        {"key_3":"value_3","key_4":"value_4"}
      expected_time: 3
      expected_code: 200
      expected_result:
        {"code":1,"message":"成功"}
      regular:
        variable:
          - name_1
          - name_2
        expression:
          - '"response_1":"(.+?)"'
          - '"response_2":"(.+?)"'

json 文件

[
  {
    "case_name": "用例名称",
    "step": [
      {
        "step_name": "步骤名称",
        "mysql": [],
        "pgsql": [],
        "mongo": [],
        "request_mode": "POST",
        "api": "/api/test",
        "file": [],
        "body": "{\"key_1\":\"value_1\",\"key_2\":\"value_2\"}",
        "headers": "{'Content-Type': 'application/json'}",
        "query_string": "{'key_3':'value_3','key_4':'value_4'}",
        "expected_time": 3,
        "expected_code": 200,
        "expected_result": "{\"code\":1,\"message\":\"成功\"}",
        "regular": {
          "variable": [
            "name_1",
            "name_2"
          ],
          "expression": [
            "\"response_1\":\"(.+?)\"",
            "\"response_2\":\"(.+?)\""
          ]
        }
      }
    ]
  }
]

1、外层有 2 个字段,内层有 16 个字段

命名和格式不可修改,顺序可以修改

字段 中文名称 是否必填 格式 注解
case_name 用例名称
step 步骤 -列表格式 1 条用例可以有 1 个或者 N 个步骤,全部的步骤通过,本条用例才算通过
step_name 步骤名称
mysql MySQL 语句 -列表格式 顺序不可修改
pgsql PgSQL 语句 -列表格式 顺序不可修改
mongo Mongo 语句 -列表格式 顺序不可修改
request_mode 请求方式
api 接口路径
file 文件 -列表格式 顺序不可修改
body 请求体 缩进字典格式或者 json 格式
headers 请求头 缩进字典格式或者 json 格式
query_string 请求参数 缩进字典格式或者 json 格式
expected_time 预期的响应时间
expected_code 预期的响应代码
expected_result 预期的响应结果 -列表格式、缩进字典格式或者 json 格式
regular 正则 缩进字典格式
variable 变量名 -列表格式
expression 表达式 -列表格式

2、mysql 字段说明

mysql: MySQL 语句,-列表格式,顺序不可修改,选填

位置 索引 作用 是否必填 格式 注解
第一行 mysql[0] 增删改 字符串 增、删、改语句
第二行 mysql[1] 字符串 查语句(动态传参)
第三行 mysql[2] 字符串 查语句(数据库双重断言)

第一行:mysql[0]

第二行:mysql[1]

第三行:mysql[2]

第一行为增、删、改语句,第二行为查语句(动态传参),第三行为查语句(数据库双重断言)

第一行是发起请求之前的动作,没有返回结果

第二行是发起请求之前的动作,有返回结果,是为了动态传参

第三行是发起请求之后的动作,有返回结果,但是不可用于动态传参,是为了断言实际的响应结果

当不需要增删改查和双重断言时,可以不写 mysql 字段,或者三行都为空

当只需要增删改时,第一行为增删改语句,第二行为空,第三行为空

当只需要查时,第一行为空,第二行为查语句,第三行为空

当只需要双重断言时,第一行为空,第二行为空,第三行为查语句

3、pgsql 字段说明

pgsql: PgSQL 语句,-列表格式,顺序不可修改,选填

位置 索引 作用 是否必填 格式 注解
第一行 pgsql[0] 增删改 字符串 增、删、改语句
第二行 pgsql[1] 字符串 查语句(动态传参)
第三行 pgsql[2] 字符串 查语句(数据库双重断言)

第一行:pgsql[0]

第二行:pgsql[1]

第三行:pgsql[2]

第一行为增、删、改语句,第二行为查语句(动态传参),第三行为查语句(数据库双重断言)

第一行是发起请求之前的动作,没有返回结果

第二行是发起请求之前的动作,有返回结果,是为了动态传参

第三行是发起请求之后的动作,有返回结果,但是不可用于动态传参,是为了断言实际的响应结果

当不需要增删改查和双重断言时,可以不写 pgsql 字段,或者三行都为空

当只需要增删改时,第一行为增删改语句,第二行为空,第三行为空

当只需要查时,第一行为空,第二行为查语句,第三行为空

当只需要双重断言时,第一行为空,第二行为空,第三行为查语句

4、mongo 字段说明(参考 mysql 字段)

mongo: Mongo 语句,-列表格式,顺序不可修改,选填

位置 索引 作用 是否必填 格式 注解
第一行 mongo[0] 增删改 -列表格式 第一个元素为集合名,第二个元素为增删改,第三个元素为增删改参数
第二行 mongo[1] -列表格式 第一个元素为集合名,第二个元素为查参数
第三行 mongo[2] -列表格式 第一个元素为集合名,第二个元素为查参数

第一行:mongo[0]

第二行:mongo[1]

第三行:mongo[2]

第一行为增、删、改,第二行为查(动态传参),第三行为查(数据库双重断言)

第一行是发起请求之前的动作,没有返回结果

第二行是发起请求之前的动作,有返回结果,是为了动态传参

第三行是发起请求之后的动作,有返回结果,但是不可用于动态传参,是为了断言实际的响应结果

当不需要增删改查和双重断言时,可以不写 mongo 字段,或者三行都为空

当只需要增删改时,第一行为增、删、改,第二行为空,第三行为空

当只需要查时,第一行为空,第二行为查,第三行为空

当只需要双重断言时,第一行为空,第二行为空,第三行为查

5、file 字段说明

file: 文件参数,-列表格式,顺序不可修改,选填

位置 类型 是否必填 格式 注解
第一行 文件类型 字符串 例如:file
第二行 文件名称 字符串 例如:demo_excel.xlsx
第三行 MIME 类型 字符串 例如:application/octet-stream

6、函数助手

函数名称 写法 作用域 数量限制
正则表达式提取的结果 ${变量名} 全局 不限
MySQL 查询语句返回的结果 {__SQL 索引} 本条用例 不限
PgSQL 查询语句返回的结果 {__PGSQL 索引} 本条用例 不限
Mongo 查询语句返回的结果 {__MONGO 索引} 本条用例 不限
随机数字 {__RN 位数} 本条用例 不限
随机英文字母 {__RL 位数} 本条用例 不限
随机手机号码 {__MP} 本条用例 不限
随机日期时间字符串 {__RD 开始年份,结束年份} 本条用例 不限

正则表达式提取的结果用 ${变量名}匹配,一条用例里面可以有多个

MySQL 查询语句返回的结果,即第二行 mysql[1] 返回的结果,用{SQL 索引}匹配

即{
SQL0}、{SQL1}、{SQL2}、{SQL3}。。。。。。一条用例里面可以有多个

PgSQL 查询语句返回的结果,即第二行 pgsql[1] 返回的结果,用{
PGSQL 索引}匹配

即{PGSQL0}、{PGSQL1}、{PGSQL2}、{PGSQL3}。。。。。。一条用例里面可以有多个

Mongo 查询语句返回的结果,即第二行 mongo[1] 返回的结果,用{MONGO 索引}匹配

即{
MONGO0}、{MONGO1}、{MONGO2}、{MONGO3}。。。。。。一条用例里面可以有多个

随机数字用{
RN 位数},如{RN15},一条用例里面可以有多个

随机英文字母用{
RL 位数},如{RL10},一条用例里面可以有多个

随机手机号码用{
MP},一条用例里面可以有多个

随机日期时间字符串用{RD 开始年份,结束年份},如{RD2019,2020},一条用例里面可以有多个

以上 8 种类型在一条用例里面可以混合使用

${变量名}的作用域是全局的,其它 7 种的作用域仅限该条用例


四、运行

1、pytest 模式:

pytest+--cmd=环境缩写

pytest --cmd=dev

开发环境

pytest --cmd=test

测试环境

pytest --cmd=pre

预生产环境

pytest --cmd=formal

生产环境

2、yamlpy 模式:

yamlpy+run+--c=环境缩写

yamlpy run --c=dev

开发环境

yamlpy run --c=test

测试环境

yamlpy run --c=pre

预生产环境

yamlpy run --c=formal

生产环境

3、运行结果:

会在 report_log 目录下生成以下文件

allure-report

log 年月日.log

report.html

report.xml

test_case.csv

test_case.html

test_case.json

test_case.xlsx

test_case.yaml


五、打包镜像,运行容器

docker pull registry.cn-hangzhou.aliyuncs.com/yangjianliang/yamlapi:0.0.8

从阿里云镜像仓库拉取 yamlapi 镜像

docker build -t demo_image .

docker build -t 镜像名称 .

本地打包,demo_image 为镜像名称,随便取

docker run -e cmd="环境缩写" 镜像名称:latest

docker run -e cmd="dev" demo_image:latest

开发环境

docker run -e cmd="test" demo_image:latest

测试环境

docker run -e cmd="pre" demo_image:latest

预生产环境

docker run -e cmd="formal" demo_image:latest

生产环境

共收到 3 条回复 时间 点赞

大佬!

合并所有 yaml 文件,一次性读,如果 yaml 文件很多或者内容很多,不会有问题吗?比如内存不够

江诗 回复

还好吧,我写测试用例一般是一个测试工程对应一个微服务,最多一千多条用例吧,不会很大,暂时还没遇到内存不够的情况。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册