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

news2025/2/28 3:13:48

目录

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

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

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:
    @classmethod
    def get_log(cls):
        cls.log = None
        if cls.log is None:
            # 1、获取日志器
            cls.log = logging.getLogger()
            # 设置日志级别 info
            cls.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会自动记录cookie
            self.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 HOST


class ApiApproveTrust:
    # 初始化
    def __init__(self, session):
        # 获取session对象
        self.session = session
        # 认证url
        self.__url_approve = HOST + "/member/realname/approverealname"
        # 查询认证状态url
        self.__url_approve_status = HOST + "/member/member/getapprove"
        # 开户url
        self.__url_trust = HOST + "/trust/trust/register"
        # 图片验证码url
        self.__url_img_code = HOST + "/common/public/verifycode/{}"
        # 充值url
        self.__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 HOST


class ApiApproveTrust:
    # 初始化
    def __init__(self, session):
        # 获取session对象
        self.session = session
        # 认证url
        self.__url_approve = HOST + "/member/realname/approverealname"
        # 查询认证状态url
        self.__url_approve_status = HOST + "/member/member/getapprove"
        # 开户url
        self.__url_trust = HOST + "/trust/trust/register"
        # 图片验证码url
        self.__url_img_code = HOST + "/common/public/verifycode/{}"
        # 充值url
        self.__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 unittest

import requests

from api.api_register_login import ApiRegisterLogin


class 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 unittest

import requests
from parameterized import parameterized

from api import log
from api.api_approve_trust import ApiApproveTrust
from api.api_register_login import ApiRegisterLogin
from util import parser_html, read_json


class 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 OK
            self.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、提取html
    html = result.json().get("description").get("form")
    # 2、获取bs对象
    bs = BeautifulSoup(html,"html.parser")
    # 3、提取url
    url = 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.coloradmin.cn/o/2279108.html

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

相关文章

Sqlmap入门

原理 在owasp发布的top10 漏洞里面&#xff0c;注入漏洞一直是危害排名第一&#xff0c;其中数据库注入漏洞是危害的。 当攻击者发送的sql语句被sql解释器执行&#xff0c;通过执行这些恶意语句欺骗数据库执行&#xff0c;导致数据库信息泄漏 分类 按注入类型 常见的sql注入…

Maven在Win10上的安装教程

诸神缄默不语-个人CSDN博文目录 这个文件可以跟我要&#xff0c;也可以从官网下载&#xff1a; 第一步&#xff1a;解压文件 第二步&#xff1a;设置环境变量 在系统变量处点击新建&#xff0c;输入变量名MAVEN_HOME&#xff0c;变量值为解压路径&#xff1a; 在系统变…

C# OpenCvSharp 部署3D人脸重建3DDFA-V3

目录 说明 效果 模型信息 landmark.onnx net_recon.onnx net_recon_mbnet.onnx retinaface_resnet50.onnx 项目 代码 下载 参考 C# OpenCvSharp 部署3D人脸重建3DDFA-V3 说明 地址&#xff1a;https://github.com/wang-zidu/3DDFA-V3 3DDFA_V3 uses the geometri…

SpringMVC (2)

目录 1. RequestMapping 注解介绍 2. RequestMapping 使用 3. RequestMapping与请求方式 3.1 RequestMapping 支持Get和Post类型的请求 3.2 RequestMapping 指定接收某种请求 3.3 GetMapping和PostMapping 4. 传参 4.1 通过查询字符串传参 4.2 在 Body 中传参 4.2.1 …

Python爬虫学习前传 —— Python从安装到学会一站式服务

早上好啊&#xff0c;大佬们。我们的python基础内容的这一篇终于写好了&#xff0c;啪唧啪唧啪唧…… 说实话&#xff0c;这一篇确实写了很久&#xff0c;一方面是在忙其他几个专栏的内容&#xff0c;再加上生活学业上的事儿&#xff0c;确实精力有限&#xff0c;另一方面&…

力扣 打家劫舍

动态规划&#xff0c;当前状态由前两个状态获得&#xff0c;滚动数组。 题目 从题可以看出要达到最高金额时&#xff0c;要从相邻的房屋拿。因此是当前房屋的金额隔一个做累加&#xff0c;当然还需要跟前一个相邻的房屋做比较&#xff0c;便于取到哪边金额更高&#xff0c;因此…

Banana Pi BPI-RV2 RISC-V路由开发板采用矽昌通信SF2H8898芯片

Banana Pi BPI-RV2 开源网关是⼀款基于矽昌SF2H8898 SoC的设备&#xff0c;1 2.5 G WAN⽹络接⼝、5 个千兆LAN ⽹络接⼝、板载 512MB DDR3 内存 、128 MiB NAND、16 MiB NOR、M.2接⼝&#xff0c;MINI PCIE和USB 2.0接⼝等。 Banana Pi BPI-RV2 开源网关是矽昌和⾹蕉派开源社…

ESP8266-01S、手机、STM32连接

1、ESP8266-01S的工作原理 1.1、AP和STA ESP8266-01S为WIFI的透传模块&#xff0c;主要模式如下图&#xff1a; 上节说到&#xff0c;我们需要用到AT固件进行局域网应用&#xff08;ESP8266连接的STM32和手机进行连接&#xff09;。 ESP8266为一个WiFi透传模块&#xff0c;和…

【BUUCTF】[GXYCTF2019]BabySQli

进入页面如下 尝试万能密码注入 显示这个&#xff08;qyq&#xff09; 用burp suite抓包试试 发现注释处是某种编码像是base编码格式 MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5 可以使用下面这个网页在线工具很方便…

CSS基础知识 ----- 学习

介绍 CSS&#xff08;Cascading Style Sheets&#xff09;是一种用于定义网页样式和布局的样式表语言。 它与 HTML 一起用于构建 Web 页面&#xff0c;HTML 负责定义页面的结构和内容&#xff0c;而 CSS 则负责控制页面的外观和样式(各种元素的字体,颜色,大小,间距,边距)。 …

计算机网络 (50)两类密码体制

前言 计算机网络中的两类密码体制主要包括对称密钥密码体制&#xff08;也称为私钥密码体制、对称密码体制&#xff09;和公钥密码体制&#xff08;也称为非对称密码体制、公开密钥加密技术&#xff09;。 一、对称密钥密码体制 定义&#xff1a; 对称密钥密码体制是一种传…

Asp.Net Core 8.0 使用 Serilog 按日志级别写入日志文件的两种方式

1、所需的Nuget包 本文项目的版本是.NET 8.0&#xff0c;如果使用其它版本安装适配版本即可。 Serilog.AspNetCore(8.0.2) Serilog.Sinks.File(5.0.0) Serilog.Expressions(5.0.0) 2、两种配置方式 2.1 代码形式&#xff08;Program.cs&#xff09; 在Program.cs文件中&am…

华为HuaweiCloudStack(一)介绍与架构

本文简单介绍了华为HCS私有云解决方案&#xff0c;并从下至上介绍HCS的整体架构&#xff0c;部署架构、部署方式等内容。 目录 HCS简介 HCS架构 纵向结构 ?管理平台类型 HCS节点类型 FusionSphere OpenStack CPS ServiceOM SC 运营面 OC 运维面 HCS部署架构 regi…

彻底讲清楚 单体架构、集群架构、分布式架构及扩展架构

目录 什么是系统架构 单体架构 介绍 示例图 优点 缺点 集群架构 介绍 示意图 优点 缺点 分布式架构 示意图 优点 缺点 生态扩展 介绍 示意图 优点 缺点 扩展&#xff1a;分布式服务解析 纵切拆服务 全链路追踪能力 循环依赖 全链路日志&#xff08;En…

flutter 常用UI组件

文章目录 1. Toast 文本提示框oktoastbot_toast2. loading 加载窗flutter_easyloading3. 对话框gex dialog4.下拉刷新pull_to_refresh5. pop 窗custom_pop_up_menu6. pin code 密码框pinput7. 二维码qr_flutter8. swiper 滚动组件carousel_sliderflutter_swiper_view9. Badge 角…

【王树森搜索引擎技术】概要01:搜索引擎的基本概念

1. 基本名词 query&#xff1a;查询词SUG&#xff1a;搜索建议文档&#xff1a;搜索结果标签/筛选项 文档单列曝光 文档双列曝光 2. 曝光与点击 曝光&#xff1a;用户在搜索结果页上看到文档&#xff0c;就算曝光文档点击&#xff1a;在曝光后&#xff0c;用户点击文档&…

【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)

本文项目编号 T 141 &#xff0c;文末自助获取源码 \color{red}{T141&#xff0c;文末自助获取源码} T141&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

【ArcGIS微课1000例】0140:总览(鹰眼)、放大镜、查看器的用法

文章目录 一、总览工具二、放大镜工具三、查看器工具ArcGIS中提供了三种局部查看的工具: 总览(鹰眼)、放大镜、查看器,如下图所示,本文讲述这三种工具的使用方法。 一、总览工具 为了便于效果查看与比对,本实验采用全球影像数据(位于配套实验数据包中的0140.rar中),加…

【TCP】rfc文档

tcp协议相关rfc有哪些 TCP&#xff08;传输控制协议&#xff09;是一个复杂的协议&#xff0c;其设计和实现涉及多个RFC文档。以下是一些与TCP协议密切相关的RFC文档列表&#xff0c;按照时间顺序排列&#xff0c;涵盖了从基础定义到高级特性和优化的各个方面&#xff1a; 基…

智能学习平台系统设计与实现(代码+数据库+LW)

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装智能学习平台系统软件来发挥其高效地信息处理的作用&#…