金融项目实战 06|Python实现接口自动化——日志、实名认证和开户接口

目录

一、日志封装及应用(理解)

二、认证开户接口脚本编写

1、代码编写

1️⃣api目录

2️⃣script目录

2、BeautifulSoup库

1️⃣简介及例子 

2️⃣提取html数据工具封装

3、认证开户参数化


一、日志封装及应用(理解)

🔴日志的作用:

  • 记录程序运行的步骤和错误。

🔴日志的场景:

  • 1、调试bug
  • 2、查看程序运行轨迹

🔴日志基本应用:

# 1、导包
import logging
# 2、调用日志⼊口
logging.error("出错啦,错误原因:{}".format(e))
import logging
# 设置日志级别 及保存⽂件名
logging.basicConfig(level=logging.DEBUG, filename="../log/p2p.log")
# 调用日志
logging.debug("调试信息")
logging.info("信息级别")
logging.warning("警告")
logging.error("断⾔错误!")
logging.critical("严重错误")

🔴测试人员使用的日志的入口:

  • info:记录运行步骤
  • error:记录运行错误

🔴日志底层组成介绍:了解底层是为了修改log打印出的信息进行美化封装

  • 说明:logging库底层有4大组件(日志器、处理器、格式器、过滤器)
    • 1、日志器:接受日志信息,设置日志显示级别
    • 2、处理器:控制日志显示位置或文件
    • 3、格式器:控制日志输出的显示样式
  • 关系:
    • 格式器必须关联处理器
    • 处理器必须关联日志器

🔴日志封装应用:

重组封装的目的:解决日志显示的样式、存储方式

①日志工具的封装

在util.py中添加日志工具的封装:

下面这个日志工具类可以当模板用,最多改一下保存日志的.log文件名称


import logging.handlers# 日志工具
class GetLog:@classmethoddef get_log(cls):cls.log = Noneif cls.log is None:# 1、获取日志器cls.log = logging.getLogger()# 设置日志级别 infocls.log.setLevel(logging.INFO)filepath = DIR_PATH + os.sep + "log" + os.sep + "p2p.log"# 2、获取处理器 TimedRotatingFileHandler:日志保存到文件且根据时间去分割tf = logging.handlers.TimedRotatingFileHandler(filename=filepath,when="midnight",interval=1,backupCount=3,encoding="utf-8")# 3、获取格式器fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"fm = logging.Formatter(fmt)# 4、将格式器添加到处理器中tf.setFormatter(fm)# 5、将处理器添加到日志器中cls.log.addHandler(tf)# 返回日志器return cls.log# 下面只是测试上面的工具能不能用的,如果运行成功,则会在log目录下产生p2p.log
# p2p.log文件内容类似为:2025-01-14 22:30:41,013 INFO [util.py(<module>:50)] - 信息级别测试
if __name__ == '__main__':GetLog.get_log().info("信息级别测试")

②工具使用

这做的目的只是让log=GetLog.get_log()在只要用到导api包就自动执行,实现自动调用方法;
(为什么这样用: Python中的`__init__.py`文件 -CSDN博客)

应用的级别:info、error

  • info:i记录程序运行的步骤
  • error:记录程序错误

标注地方:api和script

api层:记录程序步骤

script:记录程序执行结果、断言结果、错误原因

可以在api和script中每个方法中标注log,下面仅为示例:

# script目录中文件标注的示例
#2、获取短信验证码接口 测试@parameterized.expand(read_json("register_login.json", "phone_code"))def test02_phone_code(self,phone,imgVerifyCode,expec_text):try:# 1、调用获取图片验证码接口 -- 目的:让session对象记录cookie# 调用接口后session会自动记录cookieself.reg.api_img_code(234)# 2、调用短信验证码接口r = self.reg.api_phone_code(phone=phone,imgVerifyCode=imgVerifyCode)# 3、查看响应结果log.info("执行接口结果为:{}".format(r.text))self.assertIn(expec_text,r.text) # 使用text提取结果是更方便,json还要根据键找值log.info("执行断言通过!")except Exception as err:# 日志# print(err)log.error("断言失败,原因:{}".format(err))# 抛异常raise
# api目录中的示例
# 2、获取短信验证码接⼝ 封装def api_phone_code(self,phone,imgVerifyCode):data = {"phone": phone,"imgVerifyCode": imgVerifyCode,"type": "reg"}log.info("正在调用获取短信验证码接口,请求方法:{}, 请求url:{} 请求参数:{}".format("post", self.__url_phone_code,data))return self.session.post(url=self.__url_phone_code,data=data)

二、认证开户接口脚本编写

1、代码编写

1️⃣api目录

①结构

from config import HOSTclass ApiApproveTrust:# 初始化def __init__(self, session):# 获取session对象self.session = session# 认证urlself.__url_approve = HOST + "/member/realname/approverealname"# 查询认证状态urlself.__url_approve_status = HOST + "/member/member/getapprove"# 开户urlself.__url_trust = HOST + "/trust/trust/register"# 图片验证码urlself.__url_img_code = HOST + "/common/public/verifycode/{}"# 充值urlself.__url_recharge = HOST + "/trust/trust/recharge"# 1、认证接口 封装def api_approve(self):pass# 2、查询认证状态接口 封装def api_approve_status(self):pass# 3、开户接口 封装def api_trust(self):pass# 4、获取图片验证码接口 封装def api_img_code(self, random):pass# 5、充值接口封装def api_recharge(self,valicode):pass

②实现

from config import HOSTclass ApiApproveTrust:# 初始化def __init__(self, session):# 获取session对象self.session = session# 认证urlself.__url_approve = HOST + "/member/realname/approverealname"# 查询认证状态urlself.__url_approve_status = HOST + "/member/member/getapprove"# 开户urlself.__url_trust = HOST + "/trust/trust/register"# 图片验证码urlself.__url_img_code = HOST + "/common/public/verifycode/{}"# 充值urlself.__url_recharge = HOST + "/trust/trust/recharge"# 1、认证接口 封装def api_approve(self):# 1、请求参数data = {"realname":"华仔","card_id":"350102199003072237"}# 2、调用请求方法 难题:multipart/form-data使用:data+files来实现多消息体类型return self.session.post(url=self.__url_approve, data=data, files={"x": "y"})# 2、查询认证状态接口 封装def api_approve_status(self):return self.session.post(url=self.__url_approve_status)# 3、开户接口 封装def api_trust(self):return self.session.post(url=self.__url_trust)# 4、获取图片验证码接口 封装def api_img_code(self, random):return self.session.get(url=self.__url_img_code.format(random))# 5、充值接口封装def api_recharge(self,valicode):# 1、请求参数data = {"paymentType": "chinapnrTrust","amount": "1000","formStr":"reForm","valicode":valicode}# 2、调用请求方法return self.session.post(url=self.__url_recharge, data=data)

难点:认证接口请求参数类型为:multipart/form-data多消息类型,如何实现?

  • 解决:请求使用data+files两种参数格式,消息头会自动切换到multipart即可。
  • 示例:self.session.post(url=self.__url_approve, data=data, files={"x": "y"})
  • files={"x": "y"}只是起到占位作用,表明有文件而已。
2️⃣script目录

 

①结构

import unittestimport requestsfrom api.api_register_login import ApiRegisterLoginclass TestApproveTrust(unittest.TestCase):# 初始化def setUp(self) -> None:#1、获取session对象self.session = requests.Session()#2、实例化ApiRegisterLogin类方法self.approve = ApiRegisterLogin(self.session)#3、调用登录接口ApiRegisterLogin(self.session).api_login()# 结束def tearDown(self) -> None:self.session.close()#1、认证接口 测试def test01_approve(self):pass#2、查询认证状态接口 测试def test02_approve_status(self):pass#3、开户接口 测试def test03_trust(self):pass#4、获取图片验证码接口 测试def test04_img_code(self):pass#5、充值接口 测试def test05_recharge(self):pass

②实现

请求第三方开户接口 和 请求第三方充值接口 的代码需要后文的BeautifulSoup库知识。

此处是加了参数化的代码,参数化的其他内容看后文参数化小节。

import unittestimport requests
from parameterized import parameterizedfrom api import log
from api.api_approve_trust import ApiApproveTrust
from api.api_register_login import ApiRegisterLogin
from util import parser_html, read_jsonclass TestApproveTrust(unittest.TestCase):# 初始化def setUp(self) -> None:#1、获取session对象self.session = requests.Session()#2、实例化ApiRegisterLogin类方法self.approve = ApiApproveTrust(self.session)#3、调用登录接口ApiRegisterLogin(self.session).api_login()# 结束def tearDown(self) -> None:r = self.session.close()# 1、认证接口 测试# 认证接口不需要参数化的原因是:只有一个可测的用例,其他两个测试用例是bug,不适合拿来做实战def test01_approve(self,expect_test="提交成功"):try:r = self.approve.api_approve()# print(r.json())log.info("正在执行认证接口响应结果为:{}".format(r.text))self.assertIn(expect_test,r.text)log.info("认证接口断言成功!")except Exception as err:# 日志log.error("断言失败,原因:{}".format(err))# 抛异常raise#2、查询认证状态接口 测试# 不需要参数化的原因是:只有一个可测的用例,def test02_approve_status(self,expect_test="华"):try:r = self.approve.api_approve_status()# print(r.json())log.info("正在执行查询认证状态接口响应结果为:{}".format(r.text))self.assertIn(expect_test, r.text)log.info("查询认证状态接口断言成功!")except Exception as err:# 日志log.error("断言失败,原因:{}".format(err))# 抛异常raise#3、开户接口 测试def test03_trust(self,expect_test="form"):try:# 1、请求后台开户接口r = self.approve.api_trust()# print(r.json())log.info("正在执行开户接口响应结果为:{}".format(r.json()))self.assertIn(expect_test, r.text)log.info("认证开户断言成功!")# 2、请求第三方开户接口result = parser_html(r) # 结果为:(’http://xxxx‘,‘{'xxx':'xxx'},……’)r = self.session.post(url=result[0],data=result[1])# print(r.text) # 结果为:UserRegister OKself.assertIn("OK",r.text)log.info("请求第三方开户断言成功!")except Exception as err:# 日志log.error("断言失败,原因:{}".format(err))# 抛异常raise#4、获取图片验证码接口 测试@parameterized.expand(read_json("approve_trust.json","img_code"))def test04_img_code(self,random,expect_code):try:r = self.approve.api_img_code(random)# print(r.status_code)log.info("正在执行获取图片验证码接口响应结果为:{}".format(r.status_code))self.assertEqual(expect_code, r.status_code)log.info("断言获取图片验证码接口成功!")except Exception as err:# 日志log.error("断言失败,原因:{}".format(err))# 抛异常raise#5、充值接口 测试@parameterized.expand(read_json("approve_trust.json","recharge"))def test05_recharge(self,valicode,expect_text):try:# 1、调用图片验证码接口self.approve.api_img_code(123)# 2、充值接口r = self.approve.api_recharge(valicode)# print("充值接口响应结果:",r.text)log.info("正在执行充值接口响应结果为:{}".format(r.json()))if valicode == 8888:# # 断言self.assertIn("form", r.text)log.info("断言充值接口成功!")# 3、三方充值result = parser_html(r)  # 结果为:(’http://xxxx‘,‘{'xxx':'xxx'},……’)r = self.session.post(url=result[0], data=result[1])self.assertIn(expect_text, r.text)log.info("请求第三方充值断言成功!")else:# print("验证码错误的响应结果:",r.text)self.assertIn(expect_text,r.text)except Exception as err:# 日志log.error("断言失败,原因:{}".format(err))# 抛异常raise

2、BeautifulSoup库

1️⃣简介及例子 

说明:⼀个python解析html/xml的三方库

安装: pip install beautifulsoup4 -i https://mirrors.tuna.tsinghua.edu.cn/ 

基本用法

应用步骤:

  • 1、导包
  • 2、实例化
  • 3、调用方法

例子:

重点:

1、查找所有标签 bs.find_all("标签名") == 元素的集合 == ["元素1","元素2"]

2、查找属性 元素.get("属性名")

其他方法:

2️⃣提取html数据工具封装

 ①思路:

②实现

在工具类py文件末尾添加下面的封装方法

from bs4 import BeautifulSoup
def parser_html(result):# 1、提取htmlhtml = result.json().get("description").get("form")# 2、获取bs对象bs = BeautifulSoup(html,"html.parser")# 3、提取urlurl = bs.form.get("action")data = {}# 4、查找所有的input标签for input in bs.find_all("input"):data[input.get("name")]=input.get("value")return url, data

使用BeautifulSoup库后就可以实现三方开户和三方充值了,代码已经在前文2️⃣script目录展示过。

3、认证开户参数化

实现难点:

 

{"img_code": [{"desc": "获取图片验证码成功(随机小数)","random": 0.123,"expect_code": 200},{"desc": "获取图片验证码成功(随机整数)","random": 123,"expect_code": 200},{"desc": "获取图片验证码失败(随机数为空)","random": "","expect_code": 404},{"desc": "获取图片验证码失败(随机数为字符串)","random": "123hello","expect_code": 400}],"recharge": [{"desc": "后台充值响应成功","valicode": 8888,"expect_text": "OK"},{"desc": "后台充值响应成功","valicode": 8889,"expect_text": "验证码错误"}]
}

添加了参数化的完整认证开户script文件已在前文展示:2️⃣script目录

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

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

相关文章

浅谈云计算15 | 存储可靠性技术(RAID)

存储可靠性技术 一、存储可靠性需求1.1 数据完整性1.2 数据可用性1.3 故障容错性 二、传统RAID技术剖析2.1 RAID 02.2 RAID 12.3 RAID 52.4 RAID 62.5 RAID 10 三、RAID 2.0技术3.1 RAID 2.0技术原理3.1.1 两层虚拟化管理模式3.1.2 数据分布与重构 3.2 RAID 2.0技术优势3.2.1 自…

Spring官网构建Springboot工程

注意&#xff1a;基于Idea的 Spring Initializr 快速构建 SpringBoot 工程时需要联网。 1.进入SpringBoot官网 Spring | Home 点击QUICKSTART 点击start.spring.io进入spring initializr 2.选择依赖 3.生成工程 下载好后解压用IDEAD导入即可。

计算机的错误计算(二百一十二)

摘要 利用两个大模型计算 实验表明&#xff0c;两个大模型均进行了中肯的分析。另外&#xff0c;其中一个大模型给出了 Python代码&#xff0c;运行后&#xff0c;结果中有7位错误数字&#xff1b;而一个大模型进行加减运算时出错。 例1. 计算 下面是与一个大模型的对话…

Vue+Echarts+百度地图 实现 路径规划

实现功能: 通过选择 相关调拨&#xff0c;系统自动规划 路径&#xff0c;并且以地图的形式呈现最佳路径 技术难点: 1. vue 结合使用 echarts 2.echarts 在 vue嵌入百度地图&#xff0c;并且做出路径 曲线 最终结果:

【算法】图解两个链表相交的一系列问题

问&#xff1a; 给定两个可能有环也可能无环的单链表&#xff0c;头节点head1和head2。请实现一个函数&#xff0c;如果两个链表相交&#xff0c;请返回相交的第一个节点&#xff1b;如果不相交&#xff0c;返回null。如果两个链表长度之和为N&#xff0c;时间复杂度请达到O(N…

Go-Zero整合Goose实现MySQL数据库版本管理

推荐阅读 【系列好文】go-zero从入门到精通&#xff08;看了就会&#xff09; 教程地址&#xff1a;https://blog.csdn.net/u011019141/article/details/139619172 Go-Zero整合Goose实现MySQL数据库版本管理的教程 在开发中&#xff0c;数据库迁移和版本管理是必不可少的工作。…

JAVA:Spring Boot 集成 JWT 实现身份验证的技术指南

1、简述 在现代Web开发中&#xff0c;安全性尤为重要。为了确保用户的身份&#xff0c;JSON Web Token&#xff08;JWT&#xff09;作为一种轻量级且无状态的身份验证方案&#xff0c;广泛应用于微服务和分布式系统中。本篇博客将讲解如何在Spring Boot 中集成JWT实现身份验证…

说一说mongodb组合索引的匹配规则

一、背景 有一张1000多万条记录的大表&#xff0c;需要做归档至历史表&#xff0c;出现了大量慢查询。 查询条件是 "classroomId": {$in: ["xxx", "xxx", ..... "xxx","xxx", "xxx" ] }耗时近5秒&#xff0c;且…

更新java

下载 Java 下载 |神谕 (oracle.com)

CSS3的aria-hidden学习

前言 aria-hidden 属性可用于隐藏非交互内容&#xff0c;使其在无障碍 API 中不可见。即当aria-hidden"true" 添加到一个元素会将该元素及其所有子元素从无障碍树中移除&#xff0c;这可以通过隐藏来改善辅助技术用户的体验&#xff1a; 纯装饰性内容&#xff0c;如…

【Java设计模式-5】装饰模式:给咖啡加点“佐料”

今天咱们要探索一下Java世界里的装饰模式&#xff08;Decorator Pattern&#xff09;。为了让这个过程更加生动易懂&#xff0c;咱们就以大家都熟悉的咖啡饮品来举例吧&#xff0c;想象一下&#xff0c;你就是那个咖啡大师&#xff0c;要给顾客调制出各种独特口味的咖啡哦&…

C++(5)

1.运算符重载 头文件 #ifndef MYSTRING_H #define MYSTRING_H#include <iostream> #include <cstring>using namespace std;class myString { private:char *str;//C风格字符串int size0; public:std::string s_str;//转换构造函数myString(const std::string &a…

K8S--配置存活、就绪和启动探针

目录 1 本人基础环境2 目的3 存活、就绪和启动探针介绍3.1 存活探针3.2 就绪探针3.3 启动探针 4 探针使用场景4.1 存活探针4.2 就绪探针4.3 启动探针 5 配置存活、就绪和启动探针5.1 定义存活探针5.2 定义一个存活态 HTTP 请求接口5.3 定义 TCP 的就绪探针、存活探测5.4 定义 g…

【HTML+CSS+JS+VUE】web前端教程-36-JavaScript简介

JavaScript介绍 JavaScript是一种轻量级的脚本语言&#xff0c;所谓脚本语言&#xff0c;指的是它不具备开发操作系统的能力&#xff0c;而是用来编写控制其他大型应用程序的“脚本” JavaScript是一种嵌入式语言&#xff0c;它本身提供的核心语法不算很多 为什么学习JavaScri…

LLM实现视频切片合成 前沿知识调研

1.相关产品 产品链接腾讯智影https://zenvideo.qq.com/可灵https://klingai.kuaishou.com/即梦https://jimeng.jianying.com/ai-tool/home/Runwayhttps://aitools.dedao.cn/ai/runwayml-com/Descripthttps://www.descript.com/?utm_sourceai-bot.cn/Opus Cliphttps://www.opu…

AI多模态论文解读:LLaVA-CoT:让视觉语言模型逐步推理

本文作者&#xff1a;AIGCmagic社区 猫先生 一、简 介 LLaVA-CoT引入了四个不同的阶段&#xff08;摘要、标题、推理和结论&#xff09;&#xff0c;使模型能够独立进行系统化的多阶段推理&#xff0c;显著提高了在推理密集型任务上的准确性。 编译了LLaVA-CoT-100k数据集&am…

分布式缓存redis

分布式缓存redis 1 redis单机&#xff08;单节点&#xff09;部署缺点 &#xff08;1&#xff09;数据丢失问题&#xff1a;redis是内存存储&#xff0c;服务重启可能会丢失数据 &#xff08;2&#xff09;并发能力问题&#xff1a;redis单节点&#xff08;单机&#xff09;部…

《C++11》nullptr介绍:从NULL说起

在C11之前&#xff0c;我们通常使用NULL来表示空指针。然而&#xff0c;NULL在C中有一些问题和限制&#xff0c;这就是C11引入nullptr的原因。本文将详细介绍nullptr的定义、用法和优点。 1. NULL的问题 在C中&#xff0c;NULL实际上是一个整数0&#xff0c;而不是一个真正的…

供应链数字化转型参考大型供应链系统技术架构设计方案

该文介绍了一个大型供应链系统技术架构的设计方案&#xff0c;包括整体设计、核心技术目录和应用案例。设计采用Choerodon微服务框架&#xff0c;关注海量并发、可伸缩性、安全性等方面。同时&#xff0c;方案符合大型企业结构的HR组织架构&#xff0c;支持多级组织架构和角色、…

STM32F1学习——DMA直接存储器存取

一、DMA直接存储器存取 DMA的全称是 Direct Memory Access 直接存储器存取&#xff0c;他可以提供外设和存储器间或存储器和存储器间的高速数据传输&#xff0c;无需CPU的干预。 STM32有12个DMA通道&#xff0c;由DMA1(7个通道组成)和DMA2(5个通道组成)&#xff0c;STM32F103C8…