接口自动化测试:Python+Pytest+Requests+Allure

news2025/2/23 18:16:58

本项目实现了对Daily Cost的接口测试:

  • Python+Requests 发送和处理HTTP协议的请求接口
  • Pytest 作为测试执行器
  • YAML 管理测试数据
  • Allure 来生成测试报告。

本项目是参考了pytestDemo做了自己的实现。

1. 项目结构及安装部署

项目结构

  • api: 接口封装层,如封装HTTP接口为Python接口
  • commom: 从文件中读取数据等各种工具类
  • core: requests 请求方法封装、关键字返回结果类
  • config: 环境、数据库连接等配置
  • data: 测试数据文件管理
  • operation: 关键字封装层,如把多个Python接口封装为关键字
  • pytest.ini: pytest 配置文件
  • requirements.txt: 相关依赖包文件
  • testcases: 测试用例
  • api_test: 单接口测试
  • scenario_test: 场景/业务流程测试

安装部署

  • 部署Daily Cost应用:教程
  • 下载本测试项目源代码 ,通过pip安装相应依赖pip3 install -r requirements.txt,根据实际情况修改setting.ini中的相应内容
  • 输入pytest运行测试
  • 如果想要使用Allure查看生成的测试报告,需要先安装Allure服务:brew install allure

2. 环境配置

  • 在config-setting.ini文件中定义api_root_url
  • 在common-read_data.py中实现load_ini()方法读取配置文件
  • 在需要使用api_root_url的地方调用load_ini(data_file_path),读取对应的value

3. 封装HTTP请求

  1. 封装requests请求方法:将requests中发送GET、POST、PUT、DELETE等方法封装到RestClient类中
  2. 定义被测API接口Request:在api文件夹中根据domain创建对应请求的集合类,如class User(RestClient),并定义各接口信息,如登录接口:
def login(self, **kwargs):         
    return self.post("/login", **kwargs)

4. 关键字封装

关键字应当是具有一定业务意义的。在封装关键字的时候,可以只封装一个接口,也可以调用多个接口来完成。

比如我们要测试记一笔,在接口调用成功后接口只会返回账单的ID,还需要调用查询账单明细接口,来帮助判断每个字段是否与输入时的一致,那么我们可以这样来进行测试:

  • 首先,将记一笔-查看明细的操作封装为一个关键字,在这个关键字中依次调用记一笔和查询账单明细结果,并可以自定义关键字的返回结果
  • 接着,在编写测试用例的时候,直接调用关键字来进行测试,这时就可以关键字的返回结果,断言的时候,也可以直接对关键字返回结果进行断言

再比如查询月度账单统计结果,一个接口就可以独立完成业务查询操作,我们在关键字中只调用这一个接口即可。

回到本项目,具体的代码逻辑如下:

  1. 在operation文件夹中,还是按照domain分文件来组织各关键字
  2. 在core中定义关键字返回的数据结构类 ResultBase
  3. 定义关键字,在调用对应API请求时需要明确传递接口请求参数,并定义返回结果
def bill_monthly_stat(date, token):
   header = {
       "Content-Type": "application/json",
       "Authorization": "Bearer " + token
   }
   param = {"date": date}
   res = bill_details.get_bill_monthly(params=param, headers=header)

   return ResultBase(res)

本项目中的关键字中都只封装了一个请求。

5. 单接口测试

记一笔接口为例。

  • 定义接口及关键字
// api -> bill.py : 定义接口
def create_new_bill(self, **kwargs):
    return self.post("/bill", **kwargs)

// operation -> bill.py : 定义关键字
def bill_create(category_id, type, amount, note, date, token):
    payload = {
        "categoryId": category_id,
        "type": type,
        "amount": amount,
        "note": note,
        "date": date
    }
    header = {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + token
    }
    res = bill.create_new_bill(json=payload, headers=header)

    return ResultBase(res)
  • 接口测试类
// testcases -> api_test -> bill -> test_bill_create.py
class TestBillCreate():
    @mark.smoke
    @mark.parametrize('category_id, type, amount, note, date, status_code, message', 
                    [
        ("5442d3b8-9d4a-4654-bf0b-d2249efef190", "EXPENSE", 100.01, "note1111test", "2021-12-01", 200, "操作成功"),
        ("66c22fad-be9d-481d-a445-c57d266bf938", "INCOME", 1000.01, "note1111test", "2021-12-01", 200, "操作成功")
        ])
    def test_bill_create_success(self, category_id, type, amount, note, date, status_code, message, token):
        result = bill_create(category_id, type, amount, note, date, token)
        assert result.response.status_code == status_code
        assert result.message == message
        assert result.response.json()["data"]["id"]
  • @mark.smoke是使用了pytest的mark标记功能,运行时使用命令pytest -m smoke只运行标记为smoke的用例
  • @mark.parametrize是pytest的变量参数化功能,可以实现数据驱动测试,如上所示有两条参数化数据,则该用例会应用这两条数据共执行两次
  • 调用bill_create时有一个token参数,它实际上是在conftest.py文件中定义的
  • pytest中的assert使用的是python内置的断言库

6. YAML文件管理测试数据

在上面的例子中我们在使用@mark.parametrize时直接将具体的测试数据写在了用例上方。为了后期修改维护效率更高,我们通常会将测试数据和用例分离,即可以采用yaml文件来单独管理测试数据,conftest.py可以帮助数据的读取。

  • 定义yaml文件:data -> api_test_data.yml
test_bill_create_success:
  # category_id, type, amount, note, date, status_code, message
  - ["5442d3b8-9d4a-4654-bf0b-d2249efef190", "EXPENSE", 100.01, "note1111test", "2021-12-01", 200, "操作成功"]
  - ["66c22fad-be9d-481d-a445-c57d266bf938", "INCOME", 1000.01, "note1111test", "2021-12-01", 200, "操作成功"]
  • key为测试用例对应的函数名test_bill_create_success
  • -表示value是数组
  • conftest.py中读取对应的测试数据
import pytest
import os
from common.read_data import data 

BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
def get_data(yaml_file_name):
    try:
        data_file_path = os.path.join(BASE_PATH, "data", yaml_file_name)
        yaml_data = data.load_yaml(data_file_path)
    except Exception as ex:
        pytest.skip(str(ex))
    else:
        return yaml_data

api_data = get_data("api_test_data.yml")
  • 参数化时从yaml文件中读取数据
@mark.parametrize('category_id, type, amount, note, date, status_code, message', 
                    api_data["test_bill_create_success"])

7. API场景测试

在做API测试时,除了单个接口输入输出的校验,由多个接口串联成的业务场景的测试也是必不可少的。

简单的,我们以登录后进入首页为例,接口调用为:登录 -> 查询当月账单明细列表 -> 查询当月账单统计值。

  • 定义场景测试类
// testcases -> scenario_test -> test_get_one_month_bill.py
import allure
import pytest
from operation.user import login_user
from operation.bill import one_month_bill_list_get_by_date, bill_monthly_stat

@pytest.mark.core
class TestGetOneMonthBill:

    @allure.title("01: user[yuxiaomeng] login")
    @allure.story('story_1')
    def test_user_login(self, core_env):
        result = login_user('yuxiaomeng', '20211030.y')
        assert result.status_code == 200
        assert result.data["token"]
        core_env["token"] = result.data["token"]

    @allure.title("02: get homepage info - bill details list")
    @allure.story('story_1')
    def test_get_current_month_monthly_bill_list(self, core_env):
        result = one_month_bill_list_get_by_date(core_env["date"], core_env["token"])
        assert result.status_code == 200
        assert len(result.data) == 2
        assert result.data[0]["date"] == "2021-11-11"
        assert result.data[0]["expense"] == 510.5

    @allure.title("03: get homepage info - bill monthly statistics ")
    @allure.story('story_1')
    def test_get_current_month_bill(self, core_env):
        result = bill_monthly_stat(core_env["date"], core_env["token"])
        assert result.status_code == 200
        assert result.data["expense"]
  • 其中core_env用于在接口间传递测试数据
// testcases -> scenario_test -> conftest.py
import pytest

@pytest.fixture(scope='session')
def core_env():
    return {"date": "2021-11"}

8. Allure生成测试报告

allure-pytest的详细使用方法可以参考官方文档。在这里只做简单介绍。

  • 运行测试时加上--alluredir参数可以生存报告到指定的文件夹:pytest --alluredir=/tmp/my_allure_results
  • 运行完后查看报告:allure serve /tmp/my_allure_results

END配套学习资源分享

最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

全套资料获取方式:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/619445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

未来软件测试的5个主要趋势以及软件测试进阶路线

全球各地的企业每天都在发展变化着,以应对市场挑战,满足日益成熟的客户需求。即使是正在进行的技术进步也会使软件测试专家在实践的过程中更加专注和精确。 2021年给软件测试领域带来了新的技术解决方案,以及质量保证和软件测试的实现。与此同…

无线蓝牙耳机哪个品牌好?十款精选的无线蓝牙耳机品牌推荐

蓝牙耳机是一种无线耳机,其通过蓝牙技术与其他设备进行连接,例如手机、电脑、平板电脑等。蓝牙耳机使得用户可以在不受线缆限制的情况下享受音频体验,而且还可以方便地进行通话,目前市场上有许多不同种类和品牌的蓝牙耳机&#xf…

如何利用Python爬虫抓取某眼查网站中的q业信息?

部分数据来源:ChatGPT 引言: 最近在朋友圈看到了一个Python爬虫兼职的机会,但是由于一些原因我没有接到,于是我自己写了一个某眼查搜索结果爬取的Python脚本。下面将分享这个脚本的详细使用教程。 背景 某眼查是一家经营企业信用信息服务的公司,可以通过其网站查询公司信…

ChimeraX - 修改 Multimer 中单链的显示颜色

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/131087434 ChimeraX 软件是一款用于分子可视化和分析的先进工具,可以处理大型数据集,支持多种格式,提…

什么是内存溢出?什么是内存泄露?

文章目录 一、什么是内存溢出? 二、什么是内存泄露? 三、如何避免内存溢出和内存泄露? 一、什么是内存溢出? 假设我们JVM中可用的内存空间只有3M,但是我们要创建一个5M的对象,那么新创建的对象就放不进去了…

十四、混合

第一部分 概念: 1) 引入 OpenGL ES 混合本质上是将 2 个片元的颜色进行调和,产生一个新的颜色。OpenGL ES 混合发生在片元通过各项测试之后,准备进入帧缓冲区的片元和原有的片元按照特定比例加权计算出最终片元的颜色值,不再是新…

07SpringCloud Gateway服务网关

目标 目标 1、服务网关 Gateway 2、ServerWebExchange 3、Gateway使用Bucket4j限流 服务网关Gateway API 网关是一个服务,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API 网关封装了系统内部架构,为每个客户端提供一…

数据湖和数据仓库区别介绍

从数据仓库到数据湖 仓库和湖泊 仓库是人为提前建造好的,有货架,还有过道,并且还可以进一步为放置到货架的物品指定位置。 而湖泊是液态的,是不断变化的、没有固定形态的,基本上是没有结构的,湖泊可以是由…

项目上线出Bug!为什么你作为测试没测出来?

材料收集 你服务于一个数据库查询业务,某次客户现场反馈查询某个语句长时间未返回结果,耗时已经远远超过项目对外提供的性能报告承诺给用户最长查询时间。 问题和相关日志已经传递回来,开发人员进行原因分析和故障修复,测试人员进…

Ubuntu系统denyhosts的使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、denyhosts是什么?二、安装denyhosts1.下载安装包2.安装3.配置4.启动5.测试 总结 前言 今天服务器又被攻击了,防火墙也打开了&#…

劝退忠告:外包实在是太坑了,划水三年,感觉人都废了

先说一下自己的情况,专科生,19年通过校招进入杭州某个外包软件公司,干了接近3年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了3年的功…

Linux使用者必备-13款厉害到让人怒赞的工具大揭秘

本文介绍几款 Linux 运维比较实用的工具,希望对 Linux 管理员有所帮助。 1、查看进程占用带宽情况-Nethogs Nethogs 是一个终端下的网络流量监控工具可以直观的显示每个进程占用的带宽。 下载:http://sourceforge.net/projects/nethogs/files/nethogs…

【MVS+DepthFilter】video-based real-time multi view stereo

1.SVO 半直接视觉里程计 2. SVO2系列之深度滤波DepthFilter 3. SVO(SVO: fast semi-direct monocular visual odometry) 4. svo_note 5. MVSDepthFilter: video-based real-time multi view stereo 6. 作者George Vogiatzis主页 video-based real-time m…

Java版Spring cloud 企业电子招投标系统源码

一、立项管理 1、招标立项申请 功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。 2、非招标立项申请 功能点:非招标立项申请入口、用户可以保存为草稿、提交。 3、采购立项列表 功能点:对草稿进行编辑&#x…

Pytorch版本的Ernie Health源码详解

Pytorch版本的Ernie Health源码详解 一、目录架构 二、尝试使用Ernie Health import torch # 查看torch版本 torch.__version__ 1.12.0cpu# 查看设备是否有GPU资源 # device torch.device(cuda:0 if torch.cuda.is_available() else cpu) device cuda if torch.cuda.is_ava…

I.MX6ULL_Linux_驱动篇(37) linux系统定时器

定时器是我们最常用到的功能,一般用来完成定时功能,本章我们就来学习一下 Linux 内核提供的定时器 API 函数,通过这些定时器 API 函数我们可以完成很多要求定时的应用。 Linux内核也提供了短延时函数,比如微秒、纳秒、毫秒延时函数…

Python selenium爬取影评生成词云图

文章目录 问题描述效果截图如下问题分析前期准备完整代码及解释字体素材 问题描述 通过中文分词、过滤停用词、生成词云图等步骤对评论数据进行处理和可视化。 效果截图如下 非常nice 问题分析 该程序需要使用 Selenium 库来模拟浏览器操作,因此需要下载安装 Chr…

@Autowired VS @Resource

一、两者的区别 首先,两者都是通过注解来实现依赖注入 。不同的话有以下几点: Autowired 是 Spring 提供的注解,所以只有 Spring 的 IoC容器 支持该注解。Resource 是 JSR-250 提供的(是 Java 的标准 ),我…

CnOpenData·A股上市公司标准数据

一、数据简介 按照《中华人民共和国标准化法》的定义,标准是指农业、工业、服务业以及社会事业等领域需要统一的技术要求。标准作为一种通用性的规范语言,在合理利用国家资源、保障产品质量、提高市场信任度、促进商品流通、维护公平竞争、保障安全等方面…

Hash算法的特点、应用和实现方法详解

什么是Hash算法?Hash算法,简称散列算法,也成哈希算法(英译),是将一个大文件映射成一个小串字符。与指纹一样,就是以较短的信息来保证文件的唯一性的标志,这种标志与文件的每一个字节…