接口自动化测试框架 pytest+ymal+allure+requests


文章目录

  • 接口自动化测试框架 pytest+ymal+allure+requests
  • 前言
  • 一、目录结构
  • 二、关键文件介绍
  • 1.yaml测试数据格式
  • 1.1 本地缓存介绍
  • 保存本地缓存方法为3种
  • 读取本地缓存方法
  • 1.2 接口关联介绍
  • 1.3 参数介绍
  • 1.4 断言介绍
  • 1.4 生成随机数据介绍
  • 1.5 整体yaml展示
  • 2.config.ini配置文件格式
  • 三、操作方法
  • 四、代码展示
  • 总结



前言

框架采用python的pytest模块,
搭配requests以及allure测试报告,可以发送钉钉通知邮件通知
可以根据yaml测试数据自动生成用例,
支持接口关联,
支持类似jmeter的函数助手,
可以通过脚本进行接口录制,辅助编写yaml测试数据文件,
支持数据库断言,
支持分布式,jenkins持续集成。


一、目录结构

|--接口自动化测试框架 # 主目录
   ├─ common # 封装断言以及requests的方法
   ├─ caches # 本地缓存保存路径
   ├─ config # 配置文件读取
     └─ config.ini
   ├─ testsuite # 测试相关文件
     ├─ datas #测试数据
       └─ 项目文件夹 名称同config中 testname一致 # 可以通过newproject脚本生成
          └─ login.yml # 用例数据 格式参考下面YAML PARAM格式说明
     ├─ testcase
       └─ 项目文件夹 名称同config中 testname一致 # 测试用例 可以通过writepage脚本生成
         └─ test_login.py
     └─recording # 录制脚本文件夹放录制的接口文档
   ├─ util # 常用工具 用例生成 接口录制
     ├─ tools # 内部调用工具方法包含yaml读取 函数助手 数据库链接等
     └─ scripts # 包含生成新项目,自动生成用例,接口录制
   ├─ log # 日志
   ├─ report # allure测试报告	
   ├─ pytest.ini	   # pytest配置
   ├─ requirements.txt		 
   ├─ README.md          
   └─ setupMain.py	# 整体执行程序。

二、关键文件介绍

1.yaml测试数据格式

1.1 本地缓存介绍

保存本地缓存方法为3种
1. body  请求体内的参数中保存:
       body如果是 "id=2&path=haha" 会转换成字典 然后根据path使用jsonpath取值
    2. response : 从json格式的响应结果中获取
    3. cookies: 保存响应结果的cooies到本地
读取本地缓存方法

将需要替换为缓存数据的内容改成:$caches(cookies)$

示例:

cache: # 本地缓存
      - cachefrom: 'body' 
        path: '$.code' 
        name: 'code'
        # 使用方法 需要的地方替换为$caches(code)$
      - cachefrom: 'response' 
        path: '$.data'
        name: 'data'
        # 使用方法 需要的地方替换为$caches(data)$
      - cachefrom: 'cookies' 
        path:  # cookies 时path为空
        name: 'cookies'
        # 使用方法 需要的地方替换为$caches(cookies)$

1.2 接口关联介绍

通过relevance字段来判断是否需要关联
如果不需要relevance字段为空即可

示例:

下面示例为 关联接口为tradeAdd 与 tradeAdd2两条yaml数据中case的第一条和第二条
分别去这两个接口返回结果的 id 并命名为tradeId 、tradeId2
内存中会保存成字典格式
{"tradeId":"10","tradeId2":"11"}

relevance:
      - relCaseName: tradeAdd # 其他testcase的ID
        relCaseNum: 1 # 关联的case数组里 第几条数据
        value: $.id # 当前返回结果的jsonpath
        name: tradeId # 关联值名称 
      - relCaseName: tradeAdd2 # 其他testcase的ID
        relCaseNum: 2 # 关联的case数组里 第几条数据
        value: $.id # 当前返回结果的jsonpath
        name: tradeId2 # 关联值名称

1.3 参数介绍

file : 通过case外关键字file判断是否需要上传文件 如果需要则格式为:{上传文件的参数名:文件路径}

param:包含两种请求格式
(1)json格式 { "username": "finsiot","password": "$caches(pwd)$" # 读取缓存值 } (2)param格式 username=admin&password=123

urlparam{ id: 123 } 路径参数 addressv1/api/$url(id)$/中会根据id替换为123

data:
      file: {
        files: D:\test\test.csv # 上传文件的参数名:文件路径
      }
      param: {
        "username": "finsiot","password": "$caches(pwd)$" # 读取缓存值
      }
      urlparam: {
      id: 123
      }# 路径参数 v1/api/$url(id)$/

1.4 断言介绍

jsonpath json格式数据断言:
根据json路径格式来获取实际结果同value中的预期结果进行判断
sqlassert 数据库结果断言
可同时判断多个结果值
根据sql中的查询语句查询出来的 第一条结果进行判断
time响应时间断言 默认为2秒
code http响应码断言

assert:
      jsonpath:
        - {
          "path": "$.data.expense_trend[0].peak_hour.peak_hour",
          "value": "123",  # 预期结果
          "asserttype": "==" # 判断相等
        }
        - {
          "path": "$.code",
          "value": 0,
          "asserttype": "=="
        }
        - {
          "path": "$.data.id",
          "value": 196,
          "asserttype": "=="
        }
      sqlassert:
      # 如果不需要 此字段置空即可
        - {
          "datas": [
            {
              "path": "$.data.id",
              "name": "id"
            },
            {
              "path": "$.data.username",
              "name": "username"
            },
          ],
          "sql": "select * from saas.user where username = '****'", 
           # 取数据库查询出的第一条数据进行验证 如果存在 列名 username 值为$.data.username则通过
          "db_name": "database" # 判断链接那个数据库
          }
      time: 2 # 响应时间断言
      code: 200

1.4 生成随机数据介绍

部分数据采用faker库生成

int_num = "$RandomPosInt(1,333)$" # 267
    str_num = '$RandomString($RandomPosInt(2,23)$)$$RandomPosInt(1,333)$' # AbE3c14580f29aDFe5
    float_num = '$RandomFloat($RandomPosInt(2,13)$,$RandomPosInt(2,13)$,$RandomPosInt(2,13)$)$' # 11.84864
    time_num = '$GetTime(time_type=else,layout=%Y-%m-%d %H:%M:%S,unit=0,0,0,0,0)$' # 当前时间 2022-04-14 13:27:01
    time_num2 = '$GetTime(time_type=future,layout=%Y-%m-%d %H:%M:%S,unit=0,0,0,3,0)$' # 未来时间3天后 2022-04-17 13:32:42
    time_num3 = '$GetTime(time_type=past,layout=%Y-%m-%d %H:%M:%S,unit=0,0,0,3,0)$' # 过去时间3天前 2022-04-11 13:33:24
    choice_num = '$Choice($RandomPosInt(2,13)$)$'  # 6
    email = "$faker(email)$"# 邮箱 # xkong@example.net
    idcard = "$faker(idcard)$" # 130802196003197594
    province = "$faker(province)$" # 新疆维吾尔自治区
	city = "$faker(city)$" # 鹏市
	phone_number = "$faker(phone_number)$" # 15070673645
	name = "$faker(name)$" # 许云

1.5 整体yaml展示

!!!所有case的id 务必唯一!!!

name: "登录" # 测试用例模块名称
token: Authorization# 判断此接口是否使用token false 或者"cookie"或者"Authorization"等 如果不需要 置空或者填写false
order: 1 用例执行顺序 @pytest.mark.run(order=1) # 因为此功能不支持分布式录制中已取消
file: bool值判断 true为此接口需要上传文件参数
case: 测试用例数据

login: # caseID **请务必唯一**
  name: "登录" #测试用例模块
  token: false # 判断此接口是否使用token false 或者"cookie"或者"Authorization"等
  # token: "Authorization"
  order: 1 # 用例执行顺序 @pytest.mark.run(order=1) 因为此功能不支持分布式录制中已取消
  file: true # bool值 true为需要文件的接口
  case:
  - info: "用户名登录-成功" # 用例信息
    host: 'host' # config.ini里面 请求host的key
    address: '/v1/apps/$url(region_id)$/' # $url(region_id)$ 正则匹配参数中的路径参数
    method: 'post'
   
    cache: # 本地缓存
        # 保存本地缓存方法为3种
        # 1. body  请求体内的参数中保存:
        #    body如果是 "id=2&path=haha" 会转换成字典 然后根据path使用jsonpath取值
        # 2. response : 从json格式的响应结果中获取
        # 3. cookies: 保存响应结果的cooies到本地
      - cachefrom: 'body' 
        path: '$.code' 
        name: 'code'
        # 使用方法 需要的地方替换为$caches(code)$
      - cachefrom: 'response' 
        path: '$.data'
        name: 'data'
        # 使用方法 需要的地方替换为$caches(data)$
      - cachefrom: 'cookies' 
        path:  # cookies 时path为空
        name: 'cookies'
        # 使用方法 需要的地方替换为$caches(cookies)$
     
    # 接口关联
    relevance:
    # 判断如果不需要关联relevance字段为空即可
    # 如果需要关联就
      - relCaseName: tradeAdd # 其他testcase的ID
        relCaseNum: 1 # 关联的case数组里 第几条数据
        value: $.id # 当前返回结果的jsonpath
        name: tradeId # 关联值名称 
        
        
    # 机制为 根据relevance字段生成字典{"tradeId":"123"} 
    # 使用关联值方法为将需要替换的地方修改为 $relevance(tradeId)$

    headers: {
      "Content-Type": "application/json"
    }
    data:
      file: {
        files: D:\test\test.csv # 上传文件的参数名:文件路径
      }
      param: {
        "username": "finsiot","password": "$caches(pwd)$" # 读取缓存值
      }
      urlparam: {
      id: $relevance(id)$
      }# 路径参数 v1/api/$url(id)$/
    assert:
      jsonpath:
        - {
          "path": "$.data.expense_trend[0].peak_hour.peak_hour",
          "value": "123", 
          "asserttype": "=="
        }
        - {
          "path": "$.code",
          "value": 0,
          "asserttype": "=="
        }
        - {
          "path": "$.data.id",
          "value": 196,
          "asserttype": "=="
        }
      sqlassert:
      # 如果不需要 此字段置空即可
        - {
          "datas": [
            {
              "path": "$.data.id",
              "name": "id"
            },
            {
              "path": "$.data.username",
              "name": "username"
            },
          ],
          "sql": "select * from saas.user where username = '****'", 
           # 取数据库查询出的第一条数据进行验证 如果存在 列名 username 值为$.data.username则通过
          "db_name": "database" # 判断链接那个数据库
          }
      time: 2 # 响应时间断言
      code: 200 # HTTP响应码断言

2.config.ini配置文件格式

重点为[directory] 中的test_name 所有程序都围绕test_name 进行执行
根据testname来生成测试用例执行测试等

[directory] # 路径相关
log_dir = /logs
data_dir = /datas
page_dir = /page
report_xml_dir = /report/xml
report_html_dir = /report/html
test_suite = /test_suite
case_dir = /testcase
cache_dir = /caches
test_name = 测试项目名称: saasWeb
[host]
http_type = http
host = 
[email]
;服务器
mail_host = smtp.sina.com
;发送邮箱
mail_user = 
;口令
mail_pass = 
;发送者
sender = 
;接收邮箱
receivers = 
[database]
host = 192.
port = 3306
user = root
password = 
;database = 
database = 
charset = utf8
[dingding]
webhook = 
secret =

三、操作方法

  1. 新建config/config.ini文件 格式如上例子
  2. 执行util/scripts/newProject.py 根据testname生成测试项目基础目录
  3. 在生成的test_suite/datas/testname 文件夹下增加yaml测试用例
  4. 执行util/scripts/writeCase.py生成测试脚本 关于token 需要根据自己项目情况修改yaml文件中token关键字 如果不需要token值为false 需要token则改为需要的类型
  5. 执行setupMain.py开始测试

四、代码展示

test_login.py

python ui自动化测试多个页面封装 pytest封装的接口自动化框架_功能测试


login.yml

python ui自动化测试多个页面封装 pytest封装的接口自动化框架_json_02


conftest.py

python ui自动化测试多个页面封装 pytest封装的接口自动化框架_自动化_03


总结

这里给大家分享出来希望能和朋友们共同学习,共同进步