ApiTesting全链路接口自动化测试框架骑着蜗牛的测试

此框架是基于Python+Pytest+Requests+Allure+Yaml+Json实现全链路接口自动化测试。

主要流程:解析接口数据包 ->生成接口基础配置(yml) ->生成测试用例(yaml+json) ->生成测试脚本(.py) ->运行测试(pytest) ->生成测试报告(allure)
测试流程:初始化请求 ->处理接口基础信息 ->读取前置接口用例 ->发送前置接口 ->处理当前接口数据 ->发送当前接口 ->检查接口返回
接口自动化测试无非分几大块: 测试用例设计、测试 脚本编写、测试结果校验、测试报告生成、测试配置管理。
其中常见有几大难点:接口之间依赖关联、 测试数据与脚本分离、测试数据参数化处理、全量自动化耗时。

而这些本框架通通已为你解决,你无须编写任何代码,只需要你抓取接口数据包即可

关于接口依赖:你只要填写前置接口相对路径即可,如果存在数据依赖关系,此时你也仅需要填写前置接口对应的参数值,本框架将自动为你调用和替换关联数据。
关于测试数据:本框架采用yaml记录接口基本信息,当请求参数和结果较大时,将单独保存到json文件中,解决各类数据的错综复杂问题。
关于参数化:本框架采用常用工具使用的变量标识 ${var} ,通过 正则表达式,自动检索变量,自动为你替换变量,并且为你提供多种函数助手【 $RandInt()$GenGuid()】为你解决测试数据生成问题。
关于用例执行:本框架利用pytest扩展库,支持多线程模式、失败用例重试、用例模糊匹配等。

目前主要支持四种运行模式:

> 0 -不开启自动生成测试用例功能,将直接运行测试
> 1 -根据手工编写用例,自动生成测试脚本,然后运行测试
> 2 -根据接口抓包数据,自动生成测试用例和测试脚本,然后运行测试
> 3 -根据接口抓包数据,自动生成测试用例和测试脚本,但不运行测试
注意:目前解析仅支持(.chlsj)格式,请使用Charles工具抓包导出JSON Session File

目前支持多种函数助手(以下仅为示例,之后将单独说明):

print('替换变量并计算表达式:', replace('$Eval(${unitCode}*1000+1)', {'unitCode': 9876543210}))
print('生成1-9之间的随机数:', replace('$RandInt(1,9)'))
print('生成10位随机字符:', replace('$RandStr(10)'))
print('从列表中随机选择:', replace('$RandChoice(a,b,c,d)'))
print('生成一个伪手机号:', replace('$GenPhone()'))
print('生成一个guid:', replace('$GenGuid()'))
print('生成一个伪微信ID:', replace('$GenWxid()'))
print('生成一个伪身份证:', replace('$GenNoid()'))
print('生成一个18岁伪身份证:', replace("$GenNoid(y-18)"))
print('生成下个月今天的日期:', replace("$GenDate(m+1)"))
print('生成昨天此时的时间:', replace("$GenDatetime(d-1)"))

替换变量并计算表达式: 9876543210
生成1-9之间的随机数: 9
生成10位随机字符: CB8512d4E6
从列表中随机选择: d
生成一个伪手机号: 18890688629
生成一个guid: 78A6698C-6793-11EB-8221-005056C00008
生成一个伪微信ID: AUTO9K6MRzVGfsNB4ZkIuSdXravD
生成一个伪身份证: 999577202102052043
生成一个18岁伪身份证: 953700200302056259
生成下个月今天的日期: 2021-03-05
生成昨天此时的时间: 2021-02-04 17:21:04.696745

框架流程图

项目结构

 

作者:骑着蜗牛的测试
链接:https://zhuanlan.zhihu.com/p/577226317
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

启动服务(startup.py)

 -*- coding:utf-8 -*-
# @Time    : 2021/2/1
# @Author  : Leo Zhang
# @File    : startup.py
# ***********************
import os
import sys
import pytest
import logging


if __name__ == '__main__':
    from comm.script import writeLogs, writeCase
    from config import *

    # 开启日志记录(默认logs目录)
    writeLogs.MyLogs(ROOT_DIR+'logs')

    # 判断运行模式
    if RC['auto_switch'] == 3:
        logging.info("根据接口抓包数据,自动生成测试用例和测试脚本,但不运行测试!")
        writeCase.write_case(DATA_DIR, auto_yaml=True)
        sys.exit(0)

    elif RC['auto_switch'] == 2:
        logging.info("根据接口抓包数据,自动生成测试用例和测试脚本,然后运行测试!")
        writeCase.write_case(DATA_DIR, auto_yaml=True)

    elif RC['auto_switch'] == 1:
        # 如果扫描路径为空在则取项目page目录
        if not os.path.exists(RC['scan_dir']):
            RC['scan_dir'] = PAGE_DIR
        logging.info("根据手工编写用例,自动生成测试脚本,然后运行测试!")
        writeCase.write_case(RC['scan_dir'], auto_yaml=False)

    else:
        logging.info("不开启自动生成测试用例功能,将直接运行测试!")

    # 定义运行参数
    args_list = ['-vs', TEST_DIR,
                 '-n', str(RC['process']),
                 '--reruns', str(RC['reruns']),
                 '--maxfail', str(RC['maxfail']),
                 '--alluredir', REPORT_DIR+'/xml',
                 '--clean-alluredir']
    # 判断是否开启用例匹配
    if RC['pattern']:
        args_list += ['-k ' + str(RC['pattern'])]
    test_result = pytest.main(args_list)

    # 生成allure报告
    cmd = 'allure generate --clean %s -o %s ' % (REPORT_DIR+'/xml', REPORT_DIR+'/html')
    os.system(cmd)

运行配置说明(runConfig.yml)

# 运行项目名
project_name: PyDemo

# 运行模式:
auto_switch: 2
# 0 -不开启自动生成测试用例功能,将直接运行测试
# 1 -根据手工编写用例,自动生成测试脚本,然后运行测试
# 2 -根据接口抓包数据,自动生成测试用例和测试脚本,然后运行测试
# 3 -根据接口抓包数据,自动生成测试用例和测试脚本,但不运行测试
# 注意:目前解析仅支持(.chlsj)格式,请使用Charles工具抓包导出JSON Session File

# 扫描测试用例目录(且仅当auto_switch=1时有用)
scan_dir:

# 使用模糊匹配测试用例(空则匹配所有)
pattern:

# 执行并发线程数(0表示不开启)
process: 0

# 失败重试次数(0表示不重试)
reruns: 0

# 本轮测试最大允许失败数(超出则立即结束测试)
maxfail: 20

# 接口调用间隔时间(s)
interval: 1

# 测试结果校验方式说明(共5种方式):
# no_check:不做任何校验
# check_code:仅校验接口返回码code
# check_json:校验接口返回码code,并进行json格式比较返回结果(默认方式)
# entirely_check:校验接口返回码code,并进行完整比较返回结果
# regular_check:校验接口返回码code,并进行正则匹配返回结果

测试脚本基础模板(test_template.py)

# -*- coding:utf-8 -*-
# @Time    : 2021/2/2
# @Author  : Leo Zhang
# @File    : test_template.py
# ****************************
import os
import allure
import pytest
from comm.utils.readYaml import read_yaml_data
from comm.unit.initializePremise import init_premise
from comm.unit.apiSend import send_request
from comm.unit.checkResult import check_result
case_yaml = os.path.realpath(__file__).replace('testcase', 'page').replace('py', 'yaml')
case_path = os.path.dirname(case_yaml)
case_dict = read_yaml_data(case_yaml)

@allure.feature(case_dict["test_info"]["title"])
class TestTemplate:

    @pytest.mark.parametrize("case_data", case_dict["test_case"])
    @allure.story("test_template")
    def test_template(self, case_data):
        # 初始化请求:执行前置接口+替换关联变量
        test_info, case_data = init_premise(case_dict["test_info"], case_data, case_path)
        # 发送当前接口
        code, data = send_request(test_info, case_data)
        # 校验接口返回
        check_result(case_data, code, data)

接口配置示例(apiConfig.yml)

PyDemo:
  # 首次会根据接口数据包生成,可自行更改或添加新配置,所有配置将作为公共关联值
  host: 10.88.88.141:20037
  headers:
    Content-Type: application/x-www-form-urlencoded;charset=UTF-8
  cookies:
  headtoken: xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg=

测试用例说明(test.yaml)- 3.12更新

# 用例基本信息
test_info:
  # 测试用例标题,默认截取请求地址倒数第2个字段名,在报告中作为一级目录显示
  title: register
  # 请求域名,默认读取公共关联值,可修改
  host: ${host}
  # 请求协议
  scheme: http
  # 请求类型
  method: POST
  # 请求地址
  address: /api/register/findParam
  # 参数媒体类型
  mime_type: application/x-www-form-urlencoded
  # 请求头,默认读取公共关联值,可修改
  headers: ${headers}
  # 超时时长(s)
  timeout: 10
  # 是否需要上传文件
  file: false
  # 是否需要获取cookie
  cookies: false
  # 是否存在前置接口,如果存在,则填写前置接口用例相对路径,如:/register/test_getAdultCurbactList.yaml
  premise: false
  
# 测试用例,默认仅生成一个,可手动添加多个
test_case:
  # 用例概要,默认截取请求地址倒数第1个字段名
- summary: findParam
  # 用例描述,在报告中作为二级目录显示
  describe: test_findParam
  # 接口请求参数,当总字符数超过200,将转为json文件单独存储
  parameter:
    params:
      unitCode: '3202112002'
      first: 0
      pym: ''
      pageSize: 10
      page: 0
    headtoken: ${headtoken}
  # 接口检查结果
  check_body:
    # 检查类型,目前支持5种,可自行修改,默认check_json,即仅检查实际与期望结果格式是否一致
    check_type: check_json
    # 期望接口返回码
    expected_code: 200
    # 期望接口返回消息体,当总字符数超过200,将转为json文件单独存储
    expected_result:
      success: true
      code:
      msg: 返回成功
      data:
      - '1'
      - '1'
      callTime:

测试报告示例(allure)

作者:骑着蜗牛的测试
链接:https://zhuanlan.zhihu.com/p/577226317
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

核心代码(3.12新增)

script.1、接口数据包解析:依据接口数据,截取对应字段,生成测试用例yaml以及参数文件json。

script.2、测试脚本生成:依据测试用例,复制模板并修改相关字段。

script.3、运行日志收集:初始化日志模块,保存运行日志。

unit.1、请求协议方法封装:包括post、get、put、delete,以及cookie保存。

unit.2、接口发送方法封装:读取测试用例,拼接请求信息,发送请求,返回结果。

unit.3、接口初始化处理:读取公共关联配置,获取当前关联值,执行前置接口,替换关联值,返回用例信息。

unit.4、获取关联值配置:通过正则匹配${}检索关联值,然后获取消息体中的对应值。

unit.5、替换关联值:首先替换关联值,然后替换函数助手生成数据,最后替换表达式结果。

unit.6、接口结果校验:包括不检查、仅检查接口状态码、对比实际与期望结果格式、完全对比校验、正则方式校验。

utils.1、函数助手:调用不同方法来生成相关测试数据,比如生成指定长度随机字符、生成指定日期时间、生成唯一标识guid等。

实战演示

1、首先环境准备:Python + Allure (这里不做详细说明,请参考我Pytest分类博文)

接着下载项目:https://github.com/Leozhanggg/ApiTesting (方便的话给个星,不要白嫖呀,哈哈。。。)

然后加载依赖:pip install -r requirements.txt (或者使用Pycharm打开,会自动弹出提示安装)

 

 2、使用Charles工具抓取接口数据包,并且导出选择JSON Session File (.chlsj) 格式 (工具自己百度下载吧)

3、新建一个项目MyTest目录和一个data目录,把抓取的接口数据包放置进来,然后修改runConfig.yml项目名为MyTest

 

4、直接开始运行,然后你就会发现项目目录多了很多文件,测试已经完成。。。没错,就是这么简单,你还可以查看allure报告。

 

 

作者:骑着蜗牛的测试
链接:https://zhuanlan.zhihu.com/p/577226317
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

谈谈我自己

以往我使用过多种基于Python的自动化测试框架,特别是robotframework,简单易上手,对于培养普通测试工程师比较迅速,但是优点同时也是缺点,由于RF自身局限性,会让简单的语法变得复杂化,

如果你不做分层处理,可能会出现一条简单的测试用例编需要写上百行,后期维护更是非常麻烦,

我记得有一次检查测试工程师的自动化测试用例时,发现竟然有两百多行,对于RF这种表格语法两百多行你知道阅读是多么的痛苦嘛。。。

当然这也是源于我们的项目性质,由于大数据业务,接口只是一小部分,而数据的校验才是大头,

并且涉及到多类数据库,比如redis、mysql、es、hbase、solr等,而且有的接口会同时保存到多个表然后同步到多个数据库,校验点数不过来。。。

就这样前前后后我带领着几个测试工程师改了几版,虽然最后大大的减少了测试代码,但是依然还是很多,

并且运行时长很难解决。所以从去年开始使用pytest测试框架,当然这也是我首次接触pytest,第一个项目也改了几版,但是由于纯pytest编写,

所有的东西都在一块,改起来也比较简单,最终的效果当然是质的提升,首先时代码方面可以轻松的做分层处理,不会受到RF之类的框架限制,

而在执行时长方面可以采用pytest自身的多线程模块,大大减少执行时长,同时大大提高了框架的扩展性。

而本框架源于https://github.com/wangxiaoxi3/API_service项目,加上自己实际项目实施经验重构而来,保留了核心功能,增加了自己对接口自动化测试的理解。

特别对于关联值处理方面,不在需要手动标记,而采用自动检索方式,另外关于前置接口处理,也不在需要手动编写,只需要指定前置接口相对路径即可,并且多个用例可以嵌套。

另外在请求地址和消息头上,不在需要手动配置,将在接口数据解析中自动筛选消息头和请求地址,然后写入接口公共配置中,除非有变动,否则无需做任何配置。

但是目前开发的第一版并没有加入数据库校验,仅为了单纯接口的自动化测试,后期将考虑加入数据库校验模块。以下为本人实际项目数据库校验示例:

 

学习安排上

作为一位过来人也是希望大家少走一些弯路,在这里我给大家分享一些软件自动化测试的学习资源,希望能给你前进的路上带来帮助。【无套路免费白嫖】

视频文档获取方式:

这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JMeter是一款广泛使用的性能测试工具,也可以用于进行全链操作的测试,包括从登录到登出的流程。 要测试登录到登出的全链操作,首先需要准备好测试环境和测试数据。测试环境应该包括待测试的应用程序、数据库和任何相关的后端服务。测试数据应该包括各种不同的用户名和密码,以及其他相关的登录信息。 在JMeter中创建一个测试计划,并添加必要的线程组和各种配置元件。线程组是用来模拟用户并发访问的组织单元,可以设置用户数量、循环次数等参数。配置元件可以包括HTTP Cookie管理器、HTTP请求默认值等,用来设置测试过程中需要的参数和配置。 接下来,使用HTTP请求来模拟登录操作。在HTTP请求中设置好登录的URL、请求方法、请求参数等。使用提前准备好的测试数据,可以通过CSV数据文件配置HTTP请求参数。运行JMeter测试计划时,JMeter会自动从CSV文件中读取数据,并为每个用户线程分配不同的用户名和密码来进行登录请求。 登录成功后,可以根据具体的场景来设置等待时间或延迟,然后执行登出操作。同样,使用HTTP请求来模拟登出操作,设置好登出的URL、请求方法等。运行测试计划时,JMeter将模拟多个用户线程同时执行登出请求。 通过运行JMeter测试计划,可以模拟多用户并发访问应用程序的登录到登出的全链操作。可以监控并分析服务器的响应时间、吞吐量等性能指标,并查看是否有错误或异常发生。 总结起来,使用JMeter可以很方便地进行登录到登出的全链操作的性能测试,并帮助我们发现潜在的性能问题或瓶颈。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值