news 2026/1/2 12:01:50

基于Pytest+Requests+Allure实现接口自动化测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Pytest+Requests+Allure实现接口自动化测试

一、整体结构

框架组成:pytest+requests+allure

设计模式:

关键字驱动

项目结构:

工具层:api_keyword/

参数层:params/

用例层:case/

数据驱动:data_driver/

数据层:data/

逻辑层:logic/

二、具体步骤及代码

1、工具层

将get、post等常用行为进行二次封装。

代码(api_key.py)如下:

import allure import json import jsonpath import requests # 定义一个关键字类 class ApiKey: # 将get请求行为进行封装 @allure.step("发送get请求") def get(self, url, params=None, **kwargs): return requests.get(url=url, params=params, **kwargs) # 将post请求行为进行封装 @allure.step("发送post请求") def post(self, url, data=None, **kwargs): return requests.post(url=url, data=data, **kwargs) # 由于接口之间可能相互关联,因此下一个接口需要上一个接口的某个返回值,此处采用jsonpath对上一个接口返回的值进行定位并取值 @allure.step("获取返回结果字典值") def get_text(self, data, key): # json数据转换为字典 json_data = json.loads(data) # jsonpath取值 value = jsonpath.jsonpath(json_data, '$..{0}'.format(key)) return value[0]

其中引用allure.step()装饰器进行步骤详细描述,使测试报告更加详细。

使用jsonpath对接口的返回值进行取值。

2、数据层

数据采用yaml文件。

代码(user.yaml)如下:

- user: username: admin password: '123456' msg: success title: 输入正确账号、密码,登录成功 - user: username: admin1 password: '1234561' msg: 用户名或密码错误 title: 输入错误账号1、密码1,登录失败 - user: username: admin2 password: '1234562' msg: 用户名或密码错误 title: 输入错误账号2、密码2,登录失败

其中title是为了在用例进行时动态获取参数生成标题。

3、数据驱动层

对数据进行读写。

代码(yaml.driver.py)如下:

import yaml def load_yaml(path): file = open(path, 'r', encoding='utf-8') data = yaml.load(file, Loader=yaml.FullLoader) return data

4、参数层

参数层存放公共使用的参数,在使用时对其进行调用。

代码(allParams.py)如下:

''' 规则: 全局变量使用大写字母表示 ''' # 地址 URL = 'http://39.98.138.157:' # 端口 PORT = '5000'

5、逻辑层

用例一:进行登录的接口请求,此处登录请求在yaml文件里设置了三组不同的数据进行请求。

用例二:进行个人查询的接口请求,此处需要用到登录接口返回的token值。

用例三、进行添加商品到购物车的接口请求,此处需要用到登录接口返回的token值以及个人查询接口返回的openid、userid值

用例四、进行下单的接口请求,此处需要用到登录接口返回的token值以及个人查询接口返回的openid、userid、cartid值

注意:由于多数接口需要用到登录接口返回的token值,因此封装一个conftest.py定义项目级前置fixture,在整个项目只执行一次,可以在各个用例中进行调用(其他共用参数也可以采取类似前置定义)。同时由于此处定义的项目级fixture,因此可以将初始化工具类ak = ApiKey()也放入其中。

代码(conftest.py)如下:

from random import random import allure import pytest from pytest_demo_2.api_keyword.api_key import ApiKey from pytest_demo_2.params.allParams import * def pytest_collection_modifyitems(items): """ 测试用例收集完成时,将收集到的item的name和nodeid的中文显示在控制台上 """ for item in items: item.name = item.name.encode("utf-8").decode("unicode_escape") item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape") # 项目级fix,整个项目只初始化一次 @pytest.fixture(scope='session') def token_fix(): # 初始化工具类 ak = ApiKey() with allure.step("发送登录接口请求,并获取token,整个项目只生成一次"): # 请求接口 # url = 'http://39.98.138.157:5000/api/login' url = URL + PORT + '/api/login' # 请求参数 userInfo = { 'username': 'admin', 'password': '123456' } # post请求 res = ak.post(url=url, json=userInfo) # 获取token token = ak.get_text(res.text, 'token') # 验证代码,验证token只生成一次 token_random = random() return ak, token, res, token_random

其中也包含了防止中文乱码,加入了pytest_collection_modifyitems(函数)。

设置好conftest后,就可以应用在逻辑层里面了。

代码(shopingApi.py)如下:

import pytest import allure from pytest_demo_2.api_keyword.api_key import ApiKey from pytest_demo_2.params.allParams import * class ApiCase(): # 登录逻辑 def params_login(self, userdata): # 动态获取参数生成标题 allure.dynamic.title(userdata['title']) # 初始化工具类 ak = ApiKey() # 请求接口 url = URL + PORT + '/api/login' # 请求参数 userInfo = { 'username': userdata['user']['username'], 'password': userdata['user']['password'] } res = ak.post(url=url, json=userInfo) with allure.step("接口返回信息校验及打印"): print("/api/login登录接口请求响应信息") print(res.text) # 获取响应结果 msg = ak.get_text(res.text, 'msg') print(msg) # 断言 assert msg == userdata['msg'] def params_getuserinfo(self, token_fix): # 从fix中获取预置的工具类和token,所有返回值都需要接收 ak, token, res, token_random01 = token_fix with allure.step("发送个人查询接口请求"): url = URL + PORT + '/api/getuserinfo' headers = { 'token': token } res1 = ak.get(url=url, headers=headers) with allure.step("接口返回信息校验及打印"): print("/api/getuserinfo个人用户查询接口请求响应信息") print(res1.text) # print("验证的random值,测试用") # print(token_random01) name = ak.get_text(res1.text, 'nikename') # 断言 assert "风清扬" == name return res1 def params_addcart(self, token_fix): # 从fix中获取预置的工具类和token # 所有返回都要获取,不然会报错 ak, token, res, token_random01 = token_fix with allure.step("调用getuserinfo接口获取返回信息"): res1 = self.params_getuserinfo(token_fix) with allure.step("发送添加商品到购物车请求"): # 添加商品到购物车,基于token、userid、openid、productid url = URL + PORT + '/api/addcart' hd = { "token": token } data = { "userid": ak.get_text(res1.text, 'userid'), "openid": ak.get_text(res1.text, 'openid'), "productid": 8888 } # 发送请求 res2 = ak.post(url=url, headers=hd, json=data) with allure.step("接口返回信息校验及打印"): print("/api/addcart添加商品到购物车请求响应信息") print(res2.text) # print("验证的random值,测试用") # print(token_random01) result = ak.get_text(res2.text, 'result') assert 'success' == result return res2 def params_createorder(self, token_fix): ak, token, res, token_random01 = token_fix with allure.step("调用addcart接口获取返回信息"): res1 = self.params_addcart(token_fix) with allure.step("发送下单请求"): url = URL + PORT + '/api/createorder' # 从项目级fix中获取token hd = { "token": token } # 从添加商品到购物车接口中获取userid,openid,cartid data = { "userid": ak.get_text(res1.text, 'userid'), "openid": ak.get_text(res1.text, 'openid'), "productid": 8888, "cartid": ak.get_text(res1.text, 'cartid') } res2 = ak.post(url=url, headers=hd, json=data) with allure.step("接口返回信息校验及打印"): print("/api/createorder下单请求响应信息") print(res2.text) # print("验证的random值,测试用") # print(token_random01) result = ak.get_text(res1.text, 'result') assert 'success' == result

6、用例层

调用逻辑层进行用例管理和数据传输。

代码(test_Tree.py)如下:

import allure import pytest from pytest_demo_2.data_driver import yaml_driver from pytest_demo_2.logic.shopingApi import ApiCase @allure.epic("shopXo电商平台接口-接口测试") class TestTree(): # 初始化用例库 actions1 = ApiCase() @allure.feature("01.登陆") @allure.story("02.一般场景") @pytest.mark.parametrize('userdata', yaml_driver.load_yaml('./data/user.yaml')) def test_case01(self, userdata): self.actions1.params_login(userdata) @allure.feature("02.个人查询") @allure.story("01.典型场景") @allure.title("个人查询") def test_case02(self, token_fix): self.actions1.params_getuserinfo(token_fix) @allure.feature("03.添加商品到购物车") @allure.story("01.典型场景") @allure.title("添加商品到购物车") def test_case03(self, token_fix): self.actions1.params_addcart(token_fix) @allure.feature("04.下单") @allure.story("01.典型场景") @allure.title("下单") def test_case04(self, token_fix): self.actions1.params_createorder(token_fix)

7、运行

代码(main_run.py)如下:

import os import pytest def run(): pytest.main(['-v', './case/test_Tree.py', '--alluredir', './result', '--clean-alluredir']) os.system('allure serve result') # os.system('allure generate ./result/ -o ./report_allure/ --clean') if __name__ == '__main__': run()

8、结果

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/26 13:54:33

Midscene.js终极指南:让AI成为你的浏览器操作员

Midscene.js是一个革命性的AI驱动自动化框架,通过自然语言指令让AI智能操作浏览器和移动设备界面。无论你是前端开发者、测试工程师还是自动化爱好者,都能轻松上手,实现高效的界面自动化操作。 【免费下载链接】midscene Let AI be your brow…

作者头像 李华
网站建设 2025/12/18 8:16:33

3步搞定顶刊级ML图表:科研可视化终极指南

3步搞定顶刊级ML图表:科研可视化终极指南 【免费下载链接】ml-visuals 🎨 ML Visuals contains figures and templates which you can reuse and customize to improve your scientific writing. 项目地址: https://gitcode.com/gh_mirrors/ml/ml-visu…

作者头像 李华
网站建设 2025/12/18 8:15:53

跨平台浏览器插件开发实践:PT助手Plus的用户体验一致性解决方案

在当今多浏览器共存的时代,开发一款能够在Chrome、Edge、Firefox等主流浏览器中提供一致用户体验的插件,面临着诸多挑战。PT助手Plus(PT-Plugin-Plus)作为一款支持PT站点资源下载的浏览器插件,通过创新的架构设计和实践…

作者头像 李华
网站建设 2025/12/18 8:15:41

4、终端使用全攻略:从基础到高级定制

终端使用全攻略:从基础到高级定制 1. 基础操作与FTP使用 在shell提示符下输入 ftp ,会看到来自 ftp 程序的新提示符。在此提示符下,可输入特定的FTP命令,用于在本地与远程系统之间传输文件。当输入 quit (也可用 bye )这个特殊命令退出 ftp 程序时, ftp 就…

作者头像 李华