Files
apiautotest/README.md

23 KiB
Raw Blame History

前言

公司突然要求你做自动化,但是没有代码基础不知道怎么做?或者有自动化基础,但是不知道如何系统性的做自动化, 放在yaml文件中维护不知道如何处理多业务依赖的逻辑

那么本自动化框架,将为你解决这些问题。

  • 框架主要使用 python 语言编写,结合 pytest 进行二次开发,用户仅需要在 yaml 或者 excel 文件中编写测试用例, 编写成功之后,会自动生成测试用例代码,零基础代码小白,也可以操作。
  • 如果是具备代码基础的,也可以直接通过 py 文件编写测试用例。
  • 使用 Allure 生成报告,并针对测试报告样式进行了调整,使得报告更加美观;
  • 测试完成后,支持发送 企业微信通知/ 钉钉通知/ 邮箱通知,灵活配置。

一、框架介绍

本框架主要是基于 Python + Pytest + Allure + Loguru + 邮件通知/企业微信通知/钉钉通知 实现的接口自动化框架。

如果对您有帮助,请点亮 小星星 以表支持,谢谢! 对于框架有任何问题,请先仔细阅读本文~ 如果还有不了解的,欢迎联系我!

二、实现功能

  • 通过session会话方式解决了登录之后cookie关联处理`
  • 动态多断言: 如接口需要同时校验响应数据和sql校验支持多场景断言
  • 支持单独调试用例,支持用例的重复执行
  • 框架天然支持接口动态传参、关联灵活处理
  • 支持测试数据分析,测试数据不符合规范有预警机制
  • 支持通过用例数据动态配置pytest.mark 包括自定义标记pytest.mark.skip以及pytest,mark.usefixtures
  • 支持利用allure设置用例优先级运行指定优先级的用例
  • 测试数据隔离, 实现数据驱动
  • 自动生成用例代码: 测试人员在yaml/excel文件中填写好测试用例, 程序可以直接生成用例代码,纯小白也能使用
  • 支持参数多类型提取支持通过jsonpath从response.json提取数据支持通过正则表达式从response.text提取数据支持直接提取response本身的数据例如response.cookies
  • 使用Allure生成测试报告并对测试报告进行了定制化修改使得测试报告更加美观
  • 日志模块: 采用loguru管理日志可以输出更为优雅简洁的日志
  • 钉钉、企业微信通知: 支持多种通知场景,执行成功之后,可选择发送钉钉、或者企业微信、邮箱通知
  • 执行环境一键切换,解决多环境相互影响问题
  • 使用pipenv管理虚拟环境和依赖文件提供了一系列命令和选项来帮助你实现各种依赖和环境管理相关的操作
  • 支持将swagger.json接口文档转为YAML用例

三、依赖库

allure-pytest = "==2.9.45"
click = "==8.1.7"
faker = "==21.0.0"
jsonpath = "==0.82.2"
loguru = "==0.7.2"
openpyxl = "==3.1.2"
pydantic = "==2.5.2"
pymysql = "==1.1.0"
pytest-rerunfailures = "==12.0"
pyyaml = "==6.0.1"
requests-toolbelt = "==1.0.0"
"ruamel.yaml" = "==0.18.5"
sshtunnel = "==0.4.0"
xpinyin = "==0.7.6"
yagmail = "==0.15.293"
pytest-repeat = "*"

四、安装教程

  1. 通过Git工具clone代码到本地 或者 直接下载压缩包ZIP
https://gitlink.org.cn/floraachy/apiautotest.git
  1. 本地电脑搭建好 python环境我使用的python版本是3.9。包括allure测试报告所需的java环境安装jdk

  2. 安装环境依赖包

  1. 方法一使用pipenv管理所有依赖
# 安装pipenv, 这个需要全局安装。建议在项目根目录下执行命令安装
pip install pipenv

# 使用pipenv管理安装环境依赖包必须在项目根目录下执行。
pipenv install 

# 注意使用pipenv install会自动安装Pipfile里面的依赖包该依赖包仅安装在虚拟环境里不安装在测试机本机

2方法二使用requirements.txt一键安装所有依赖

pip install -r requirements.txt

# 注意:这种方式安装,会将依赖包全部安装在测试机(本机)

如上环境都已经搭建好了,包括框架依赖包也都安装好了。


注意:

  • 很多同学不太熟悉pipenv会存在问题比如我按照上述操作安装了依赖包怎么运行报错呢一定要记住使用pipenv安装依赖包依赖包只安装在虚拟环境不安装在你的测试机器。所以你安装完成后直接运行肯定会报错。我们需要进入我们创建的虚拟环境再运行测试代码。具体步骤参考章节"运行自动化测试"。
  • 如果存在Python版本与我的不一致的问题请移步最后的章节"初始化项目可能遇到的问题" 查找解决办法。
  • 另外我们如果是使用pycharm直接右键run的情况我们需要pycharm解释器选择我们创建的虚拟环境才不会报少包的错误。

五、如何创建用例

注意:如果想用我框架中的用例执行运行测试,可以暂时跳过这一章节,直接看章节 "运行自动化测试"。

1. 修改配置文件 config.settings.py

1确认用例是通过YAML还是Excel编写由CASE_FILE_TYPE控制 2确认测试完成后是否发送测试结果由SEND_RESULT_TYPE控制并填充对应邮件/钉钉/企业微信配置信息 3确认测试是否需要进行数据库断言如有需求填充数据库配置信息 4指定日志收集级别由LOG_LEVEL控制

2. 修改全局变量,增加测试数据 config.settings.py

  1. ENV_VARS["common"]是一些公共参数,如报告标题,报告名称,测试者,测试部门。后续会显示在测试报告上。如果还有其他,可自行添加 2ENV_VARS["test"]是保存test环境的一些测试数据。ENV_VARS["live"]是保存live环境的一些测试数据。如果还有其他环境可以继续增加例如增加ENV_VARS["dev"] = {"host": "", ......}

3. 删除框架中的示例用例数据

1删除 interface目录下所有的YAML和EXCEL文件(每一个文件都保存的接口测试用例) 2删除 test_case/test_manual_case目录下所有手动编写的用例,后续有需要可以在该目录下手动编写用例。

注意conftest.py文件中非业务相关的代码可以保留。

4. 编写测试用例(两种方式任选其一或者都选)

1自动生成测试用例 data test_case.test_auto_case

  • 在目录interface下新建一个YAML/Excel文件。按照如下字段要求进行测试用例数据添加
  • 注意如果需要自动创建测试用例文件YAML/Excel文件的文件名需要以"test"开头。

2手动编写测试用例 interface test_case.test_manual_case

  • 原则上如果是手动编写测试用例python代码 测试用例数据文件不要以"test"开头。 如果以“test”开头可能导致用例运行多次。 1在目录interface下新建一个YAML/Excel文件按照要求编写测试用例数据 2在test_case.test_manual_case下新建一个以"test"开头的测试方法,进行测试用例方法编写。

5. 用例中相关字段的介绍

case_common :公共参数
  allure_epic用作于@allure.epic()装饰器中的内容。
  allure_feature用作于@allure.feature()装饰器中的内容。
  allure_story用作于@allure.story()装饰器中的内容。
  case_markers: 给测试方法添加标记支持自定义标记skip, usefixtures。 格式是列表嵌套字符串或者字典。例如: # ['glcc', {'skip': '跳过执行该用例'}]
case_info: 具体的用例数据,是以列表的形式进行管理
-
  id用例id注意需要全局唯一方便后续用于用例接口依赖
  title用例标题
  severity: 用例优先级支持如下几种NORMAL BLOCKERCRITICALMINORTRIVIAL 为空和错误都认为是NORMAL
  run是否执行用例为空或者True都会执行为False则不执行。
  url请求路径可填写全路径 或者 资源路径。通常我们填写资源路径。在用例执行前会针对路径进行处理。具体可见case_utils.request_control.py.RequestPreDataHandle.url_handle。注请求路径=基准路径host/base_url+资源路径(url)。
  method请求方式例如GET, POST, DELETE, PUT, PATCH等
  headers请求头注意如果在headers里面防止cookies其值类型需要是字符串
  cookies请求cookies格式是DICT CookieJar对象
  request_type请求数据类型params, json, file, data
  payload请求参数
  files: 需要上传的文件,参考如下传参:{接口中文件参数的名称:'文件路径地址'}
  assert_response响应断言
  assert_sql数据库断言
  extract后置提取参数
  case_dependence 用例依赖

6. 参数提取说明

目前支持3种方式的参数提取type_jsonpath, type_re, type_response

type_jsonpath

如果采用jsonpath方式从响应数据提取参数extract的key是type_jsonpath; extract[type_jsonpath]的key是变量名value是提取表达式

参考示例:

  extract:
    type_jsonpath:
      nickname: $.username
      login: $.login
      user_id: $.user_id

注意如果提取到的值是长度为1的列表会自动获取第一个元素其值类型由list变更为str。例如通过name: $.data 提取到的值是:["flora"], 最后name的值会是"flora"

type_re

如果采用正则表达式方式从响应数据提取参数,extract的key是type_re; extract[type_re]的key是变量名value是提取表达式

参考示例:

  # 注意:\是用来转译的保证yaml格式正确.也可以用引号包裹起来
  extract:
    type_re:
      nickname: \"username":"(.*?)"
      login: \"login":"(.*?)"
      user_id: '"user_id":(.*?),'

注意如果提取到的值是长度为1的列表会自动获取第一个元素其值类型由list变更为str。例如通过name: "username":"(.*?)" 提取到的值是:["flora"], 最后name的值会是"flora"

type_response

如果是直接从响应数据提取参数,extract的key是type_response; extract[type_response]的key是变量名value是提取表达式

基本上response所有方法都支持部分参考response.status_code response.cookies, response.text, response.headers, response.is_redirect

参考示例:

  extract:
    type_response:
      cookies: response.cookies

6. 断言方式

以下是支持的几种断言方式:

断言方式 说明
== 相等,判断预期结果是否等于实际结果
lt 小于, 判断预期结果是否小于实际结果
le 小于等于, 判断预期结果是否小于等于实际结果
gt 大于, 判断预期结果是否大于实际结果
ge 大于等于,判断预期结果是否大于等于实际结果
not_eq 不相等,判断预期结果是否不等于实际结果
str_eq 字符串相等,判断预期结果是否等于实际结果
len_eq 长度等于,判断预期结果是否等于实际结果的长度
len_gt 长度大于,判断预期结果是否大于实际结果的长度
len_ge 长度大于等于,判断预期结果是否大于等于实际结果的长度
len_lt 长度小于,判断预期结果是否小于实际结果的长度
len_le 长度小于等于,判断预期结果是否小于等于实际结果的长度
contains 包含,判断预期结果内容被实际结果包含, 预期结果 in 实际结果
contained_by 被包含,判断预期结果包含实际结果, 实际结果 in 预期结果
startswith 以什么开头,判断实际结果是否是以预期结果开头的
endswith 以什么结尾,判断实际结果是否是以预期结果结尾的

7. 响应断言说明

断言状态码

如果想要断言接口响应码,直接这样写即可: 参考示例:

  assert_response:
    status_code: 200

响应数据断言

响应断言的参数说明:

断言标识(自定义,不为空即可,没有实际的意义):
  message: 断言信息,非必填,可为空
  expect_value: 预期结果
  assert_type: 断言类型,支持如下:==,  lt, le, gt, ge, not_eq, str_eq, len_eq, len_gt, len_ge, len_lt, len_le, contains, contained_by, startswith, endswith
  type_jsonpath: 通过jsonpath表达式从response.json()提取实际结果与type_re任选其一
  type_re: 通过正则表达式从response.text提取实际结果与type_jsonpath任选其一;如果不填则默认获取response.text作为实际结果

注意:在进行断言的时候,左侧是预期结果,右侧是实际结果。比如我断言类型是lt 那么就是预期结果<实际结果

参考示例:

  assert_response:
    user_id:
      message: 断言接口返回的user_id
      expect_value: ${user_id}
      assert_type: ==
      type_jsonpath: $.user_id
  assert_response:
    user_id:
      expect_value: ${user_id}
      assert_type: ==
      type_jsonpath: $.user_id

8. 数据库断言说明

数据库断言的参数说明:

断言标识(自定义,不为空即可,没有实际的意义):
  message: 断言信息,非必填,可为空
  sql: 数据库查询语句,必填
  expect_value: 预期结果
  assert_type: 断言类型,支持如下:==,  lt, le, gt, ge, not_eq, str_eq, len_eq, len_gt, len_ge, len_lt, len_le, contains, contained_by, startswith, endswith
  type_jsonpath: 通过jsonpath表达式通从数据库查询结果提取实际结果与type_re任选其一
  type_re: 通过正则表达式从数据库查询结果提取实际结果与type_jsonpath任选其一;如果不填则默认SQL直接查询结果作为实际结果

注意:在进行断言的时候,左侧是预期结果,右侧是实际结果。比如我断言类型是lt 那么就是预期结果<实际结果

参考示例:

    contains_user:
      message: 断言数据库查询tokens表表中存在该登录用户记录预期查询结果的长度为1
      sql: select * from tokens where user_id=${user_id};
      expect_value: 1
      assert_type: len_eq
    contains_user2:
      message: 断言数据库查询tokens表表中存在该登录用户记录;预期 ${user_id} in 查询结果jsonpath式匹配后的结果
      sql: select * from tokens where user_id=${user_id};
      type_jsonpath: $..user_id
      expect_value: ${user_id}
      assert_type: ==
    contains_user3:
      message: 断言数据库查询tokens表表中存在该登录用户记录预期 ${user_id} in 查询结果(正则表达式匹配后的结果)
      sql: select * from tokens;
      type_re: "'user_id': (.*?),"
      expect_value: ${user_id}
      assert_type: contains

9. 用例依赖说明

目前用例依赖仅支持接口依赖,数据库依赖后续会补充。 依赖的配置说明:

case_dependence: 用例依赖,为空时表示没有依赖:
  setup: 前置依赖信息,为空时表示没有依赖
    interface: 用例依赖的接口id支持str和list格式。接口id指的是每一个YAML/EXCEL用例中的ID 
    sql: 数据库查询语句,后续支持后将补充  
  teardown: 后置依赖信息,为空时表示没有依赖
    interface: 用例依赖的接口id支持str和list格式。接口id指的是每一个YAML/EXCEL用例中的ID 
    sql: 数据库查询语句,后续支持后将补充 

参考示例:

  case_dependence:
    setup:
      interface: gitlink_login_oauth_token_01
    teardown:
      interface:
        - gitlink_projects_delete_project_01
      sql:

10. Excel用例单独说明

框架支持excel多表单自动生成测试用例每一个表单作为一个测试用例模块。 例如: excel表格名称是test_demo.xlsx excel表单1名称是GitLink-登录模块 excel表单2名称是示例模块

生成规则:

  • 如果excel表单中存在"-",我们将取"-"后面的部分的首字母拼接excel文件名称作为测试用例模块/测试用例类/测试用例方法名称
  • 如果excel表单中不存在"-"我们将直接获取表单名称首字母拼接excel文件名称作为测试用例模块/测试用例类/测试用例方法名称
  • 测试用例模块/测试用例类/测试用例方法名称同时也将遵循python语法规则进行适当调整

基于上述规则:

  • excel第一个表单生成的测试用例 测试用例模块test_demo_dlmk.py 测试用例类TestDemoDlmkAuto 测试用例方法test_demo_dlmk_auto

  • excel第二个表单生成的测试用例 测试用例模块test_demo_slmk.py 测试用例类TestDemoSlmkAuto 测试用例方法test_demo_slmk_auto

六、运行自动化测试

1. 激活已存在的虚拟环境

  • 如果不存在会创建一个pipenv shell (必须在项目根目录下执行)

2. 运行

在pycharm>terminal或者电脑命令窗口进入项目根路径执行如下命令如果依赖包是安装在虚拟环境中需要先启动虚拟环境。
  > python run.py  默认在test环境运行测试用例, 生成allure测试报告
  > python run.py -m demo 在test环境仅运行打了标记demo用例生成allure测试报告
  > python run.py -env live 在live环境运行测试用例
  > python run.py -env=test 在test环境运行测试用例
  > python run.py -report=no 在test环境下允许测试用例不生成allure测试报告

注意:

  • 如果pycharm.interpreter拥有了框架所需的所有依赖包可以通过pycharm直接在run.py中右键运行

七、查看测试报告

Allure测试报告

  1. Allure生成的测试报告支持通过pycharm点击outputs/report/allure_html/index.html,文件右上角选择浏览器打开查看测试报告
  2. 如果不通过pycharm打开直接通过文件夹打开windows系统环境下可以点击outputs/report/allure_html/双击打开Allure报告.bat打开查看测试报告

注意:

  • 通过点击outputs/report/allure_html/双击打开Allure报告.bat打开测试报告的方法暂时不支持mac系统
  • 如果通过点击outputs/report/allure_html/双击打开Allure报告.bat打开测试报告,命令窗口显示乱码,或者打不开,可以把.bat的文件名称修改为英文的名称,里面的所有中文注释全部移除,再次尝试

八 、详细功能说明

  • 如何实现动态数据、随机数据的热加载? 我们有些特殊的场景,可能会涉及到一些定制化的数据,每次执行数据,需要按照指定规则随机生成,实时加载数据,那么这部分应该如何处理呢?

  • 如何处理同一环境存在多域名的情况? 很多公司,通常一套环境是由多个微服务组成。每一个微服务具备不同的域名。那么针对这种同一环境存在多域名的情况,我们应该如何处理呢?

  • 如何处理同一套框架测试多套环境的情况? 假如我想要我的自动化代码分别在不同环境执行,如何处理呢?

  • 如何处理用例中需要依赖登录的token/cookies的情况 我们进行测试的时候,很多接口都是需要先登录之后再进行操作。但是我们不可能每测试一次接口,都登录一次吧,这样有点冗余了。那么,针对这种情况如何处理呢?

  • 如何测试上传文件接口? 我们通过MultipartEncoder的方式进行文件上传。

  • 如何通过用例数据动态配置pytest.mark 在测试过程中我们经常需要对测试用例进行分类运行时仅执行这一类用例。为了实现这一功能我在测试用例中引入了添加pytest的自定义标记的功能同时扩展支持了pytest.mark.skip以及pytest,mark.usefixtues。 注意目前这一功能仅支持通过YAML格式编写用例。EXCEL用例暂时不支持。

  • 如何设置测试用例优先级 测试用例会分优先级, 我们可以利用allure的特性设置用例优先级以及运行指定优先级的用例。

  • 如何提取响应数据作为全局变量并使用? 在测试过程中,通常下一个接口需要用到上一个接口的响应数据,这个时候就涉及到参数的提取。

  • 如何进行响应数据断言以及数据库断言? 目前支持的断言方式:==, lt, le, gt, ge, not_eq, str_eq, len_eq, len_gt, len_ge, len_lt, len_le, contains, contained_by, startswith, endswith

  • 如何配置邮箱通知? 我们通过第三方模块yagmail发送邮件。

  • 如何配置钉钉通知? 我们通过封装钉钉机器人发送钉钉通知。

  • 如何配置企业微信通知? 我们通过封装企业微信机器人发送通知。

  • python虚拟管理工具--pipenv使用教程 在使用Python语言的时候我们使用pip来安装第三方包但是由于pip的特性系统中只能安装每个包的一个版本。但是在实际项目开发中不同项目可能需要第三方包的不同版本Python的解决方案就是虚拟环境。 顾名思义虚拟环境就是虚拟出来的一个隔离的Python环境每个项目都可以有自己的虚拟环境用pip安装各自的第三方包不同项目之间也不会存在冲突。 创建虚拟环境需要一些工具, 我们使用pipenv来创建虚拟环境和管理依赖包。

  • 如何调试单个用例? 有些小伙伴在测试的时候,想要单独调试用例,但是不清楚如何调试。本文将详细讲解~

  • 如何重复执行用例? 平常在做功能测试的时候经常会遇到某个模块不稳定偶然会出现一些bug对于这种问题我们会针对此用例反复执行多次最终复现出问题来。 自动化运行用例时候也会出现偶然的bug可以针对单个用例重复执行多次。

九、初始化项目可能遇到的问题

赞赏

如果这个库有帮助到你并且你很想支持库的后续开发和维护,那么你可以扫描下方二维码随意打赏我,我将不胜感激 打赏