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

目录

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

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

1、代码编写

1️⃣api目录

2️⃣script目录

2、BeautifulSoup库

1️⃣简介及例子

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

3、认证开户参数化


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

🔴日志的作用:

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

🔴日志的场景:

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

🔴日志基本应用:

python 复制代码
# 1、导包
import logging
# 2、调用日志⼊口
logging.error("出错啦,错误原因:{}".format(e))
python 复制代码
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文件名称

python 复制代码
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,下面仅为示例:

python 复制代码
# 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
python 复制代码
# 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目录

①结构

python 复制代码
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

②实现

python 复制代码
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目录

①结构

python 复制代码
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库知识。

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

python 复制代码
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文件末尾添加下面的封装方法

python 复制代码
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、认证开户参数化

实现难点:

python 复制代码
{
  "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目录

相关推荐
東雪蓮☆42 分钟前
使用 Shell 脚本监控服务器 IOWait 并发送邮件告警
linux·运维·服务器
我是海飞2 小时前
外置flash提示音打包脚本
运维·服务器·音视频·嵌入式
Source.Liu2 小时前
【Python自动化】 21.2 Pandas 读取 Excel 时的 dtype 参数完全指南
python·自动化·pandas
etcix2 小时前
for my debian 12 mxlinux install the podman
运维·debian·podman
努力努力再努力wz2 小时前
【c++进阶系列】:万字详解AVL树(附源码实现)
java·运维·开发语言·c++·redis
jingfeng5143 小时前
应用层自定义协议与序列化
运维·服务器·网络
egoist20233 小时前
[linux仓库]性能加速的隐形引擎:深度解析Linux文件IO中的缓冲区奥秘
linux·运维·开发语言·缓存·缓冲区
切糕师学AI3 小时前
持续集成和持续交付 (CI/CD) 工具——Jenkins
运维·ci/cd·jenkins
ZYMFZ4 小时前
Linux系统shell脚本(四)
linux·运维·服务器