金融项目实战 05|Python实现接口自动化——登录接口

news2025/1/16 17:45:24

目录

一、代码实现自动化理论及流程

二、脚本实现的理论和准备工作

1、抽取功能转为自动化用例

2、搭建环境(测试工具)

3、搭建目录结构

三、登录接口脚本实现 

1、代码编写

1️⃣api目录

2️⃣script目录

2、断言

3、参数化

1️⃣编写数据存储文件:json文件

2️⃣编写读取数据工具:read_json()

3️⃣参数化引用:parameterize


一、代码实现自动化理论及流程

🔴代码编写脚本和工具实现脚本区别是什么?

  • 代码:
    • 优点:代码灵活方便
    • 缺点:学习成本高
  • 工具:
    • 优点:易上手
    • 缺点:灵活度低,有局限性。
  • 总结:
    • 功能脚本:工具
    • 自动化脚本:代码

🔴代码接口自动化怎么做的?

  • 第一步:(概述)python+request+unittest; 
  • 第二步:(具体描述)封装、调用、数据驱动、日志、报告;
  • 第三步:(举例)api\scripts\data\log\report\until\...;

二、脚本实现的理论和准备工作

使用代码编写自动化脚本的流程:

  • 1、抽取功能用例转为自动化⽤例。
  • 2、搭建环境(测试工具相关的)
  • 3、搭建目录结构
  • 4、编写脚本
  • 5、执行脚本
  • 6、配置持续集成

1、抽取功能转为自动化用例

 去掉了有bug的用例、以及“请求后台投资响应失败(密码为空)”的用例(改用例需要借钱和投资双方私下协商密码)

2、搭建环境(测试工具)

①python、pycharm、requests、pymysql、parametrize

②jenkins、jdk

提示:由于编写的自动化脚本,而自动化脚本编写之前功能已测试完毕,所以不需要在单独搭建项目环境。

3、搭建目录结构

三、登录接口脚本实现 

1、代码编写

1️⃣api目录

把需要测的接口放在该目录

用到五个url,所以是5个接口,也需要在注册登录模块写五个方法

url设置成私有变量,只能在该类内部调用。

此处这样做只是因为url实际上只会在该登陆注册模块内部使用,外面没必须用到,设置私有,外部调用方法的时候。看着干净

from config import HOST

class ApiRegisterLogin:
    # 有几个接口就封装几个方法
    #初始化
    def __init__(self, session):
        # 获取session对象
        self.session = session
        # 图片url
        # 图片验证码url
        self.__url_img_code = HOST + "/common/public/verifycode1/{}"
        # 短信验证码url
        self.__url_phone_code = HOST + "/member/public/sendSms"
        # 注册Lr1
        self.__url_register = HOST + "/member/public/reg"
        # 登录url
        self.__url_login = HOST + "/member/public/login"
        # 登录状态url
        self.__url_login_status = HOST + "/member/public/islogin"


    # url
    # 1、获取图⽚验证码接⼝ 封装
    def api_img_code(self,random):
        return self.session.get(url=self.__url_img_code.format(random))

    # 2、获取短信验证码接⼝ 封装
    def api_phone_code(self,phone,imgVerifyCode):
        data = {
            "phone": phone,
            "imgVerifyCode": imgVerifyCode,
            "type": "reg"
        }
        return self.session.post(url=self.__url_phone_code,data=data)

    # 3、注册接⼝ 封装
    def api_register(self,phone,password,verifycode,phone_code):
        data = {
            "phone": phone,
            "password": password,
            "verifycode": verifycode,
            "phone_code": phone_code,
            "dy_server": "on",
            "invite_phone": ""
        }
        return self.session.post(url=self.__url_register,data=data)

    # 4、登录接⼝ 封装
    def api_login(self,keywords,password):
        data = {
            "keywords": keywords,
            "password": password
        }
        return self.session.post(url=self.__url_login, data=data)

    # 5、查询登录状态接⼝ 封装
    def api_login_status(self):
        return self.session.post(url=self.__url_login_status)
2️⃣script目录

调用封装的接口,开展测试工作

下面测试用例的内容目前只是测试一下api文件中封装的接口能不能用,后面还要改。

import unittest

import requests

from api.api_register_login import ApiRegisterLogin


class TestRegisterLogin(unittest.TestCase):
    # 初始化
    def setUp(self) -> None:
        # 获取session对象
        self.session =requests.Session()
        # 获取ApiRegisterLogin实例
        self.reg = ApiRegisterLogin(self.session)
    # 结束
    def tearDown(self) -> None:
        # 关闭session对象
        self.session.close()

    #1、获取图片验证码接口 测试
    def test01_img_code(self):
        # 调用图片验证码接口
        r = self.reg.api_img_code(234)
        # 查看响应状态码
        print(r.status_code)

    #2、获取短信验证码接口 测试
    def test02_phone_code(self,phone=17612341111,imgVerifyCode=8888):
        # 1、调用获取图片验证码接口 -- 目的:让session对象记录cookie
        # 调用接口后session会自动记录cookie
        self.reg.api_img_code(234)
        # 2、调用短信验证码接口
        r = self.reg.api_phone_code(phone=phone,imgVerifyCode=imgVerifyCode)
        # 3、查看响应结果
        print(r.json())

    #3、注册接口 测试
    def test03_register(self,phone=17612341111,imgVerifyCode=8888,password="win56",phone_code=666666):
        # 1、图片验证码接口
        self.reg.api_img_code(234)
        # 2、短信验证码接口
        self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)
        # 3、注册接口
        r = self.reg.api_register(phone=phone,password=password,verifycode=imgVerifyCode,phone_code=phone_code)
        # 4、查看结果
        print(r.json())

    #4、登录接口 测试
    def test04_login(self,keywords=17612341111,password="win56"):
        # 1、调用登录
        r = self.reg.api_login(keywords=keywords,password=password)
        # 2、查看结果
        print(r.json())

    #5、查询登录状态接口 测试
    def test05_login_status(self):
        # 调用登录擦口
        self.reg.api_login(keywords=17612341111, password="win56")
        # 调用查询登录状态接口
        r = self.reg.api_login_status()
        # 看结果
        print(r.json())

2、断言

说明:判断程序执⾏实际结果是否符合预期结果

示例

实际需要将api_register_login.py中的每个测试用例都做异常处理,下面只是以查询登录接口中的异常捕获为例。

中的完整代码后续补充。

try:
    # 调⽤登录接⼝
    self.reg.api_login(keywords="13600001111", password="test123")
    # 调⽤查询登录状态接⼝
    r = self.reg.api_login_status()
    # 看结果
    self.assertIn(expect_text, r.text)
except Exception as e:
    # ⽇志
    print(e)
    # 抛异常
    raise    
    # 提示:捕获异常的⽬的是为了将错误信息记录下来,捕获信息完成后,必须抛出异常

【提示】:捕获异常的目的是为了将错误信息记录下来,捕获信息完成后,必须抛出异常 

3、参数化

步骤

  • 1、编写数据存储⽂件 json
  • 2、编写读取⼯具⽅法 read_json()
  • 3、使⽤参数化组件进⾏引⽤ parametrize
1️⃣编写数据存储文件:json文件

心得:

1、根据模块来新建json文件(1个模块1个json⽂件)

2、最外侧使用{},模块下几个接口,编写几个key,值为列表

3、列表值中,有几组数据,就写几个{}

4、每组数据{}中,组成格式:说明+参数+预期结果

 

{
  "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
    }
  ],
  "phone_code": [
    {
      "desc": "获取短信验证码成功",
      "phone": "13600001111",
      "imgVerifyCode": 8888,
      "expect_text": "发送成功"
    },
    {
      "desc": "获取短信验证码成功",
      "phone": "13600001111",
      "imgVerifyCode": 8889,
      "expect_text": "验证码错误"
    }
  ],
  "register": [
    {
      "desc": "注册成功(必填参数)",
      "phone": 13600001111,
      "password": "test123",
      "verifycode": 8888,
      "phone_code": 666666,
      "expect_text": "注册成功"
    },
    {
      "desc": "注册失败(图片验证码错误)",
      "phone": 13600001112,
      "password": "test123",
      "verifycode": 8889,
      "phone_code": 666666,
      "expect_text": "验证码错误"
    },
    {
      "desc": "注册失败(短信验证码错误)",
      "phone": 13600001112,
      "password": "test123",
      "verifycode": 8888,
      "phone_code": 666667,
      "expect_text": "验证码错误"
    },
    {
      "desc": "注册失败(手机号已存在)",
      "phone": 13600001111,
      "password": "test123",
      "verifycode": 8888,
      "phone_code": 666666,
      "expect_text": "已存在"
    }
  ],
  "login": [
    {
      "desc": "登录成功",
      "keywords": 13600001111,
      "password": "test123",
      "expect_text": "登录成功"
    },
    {
      "desc": "登录失败(密码为空)",
      "keywords": 13600001111,
      "password": "",
      "expect_text": "不能为空"
    },
    {
      "desc": "登录失败(解锁)",
      "keywords": 13600001111,
      "password": "error123",
      "expect_text": "登录成功"
    }
  ],
  "login_status": [
    {
      "desc": "查询登录状态(已登录)",
      "status": "已登录",
      "expect_text": "OK"
    },
    {
      "desc": "查询登录状态(已登录)",
      "status": "未登录",
      "expect_text": "未登"
    }
  ]
}
2️⃣编写读取数据工具:read_json()

 

import json
import os

from config import DIR_PATH


def read_json(filename,key):
    # 拼接读取文件的完整路径
    # os.sep是动态获取/ \
    filepath = DIR_PATH + os.sep + "data" + os.sep +filename
    arr = []
    with open(filepath,"r",encoding="utf-8") as f:
        for data in json.load(f).get(key):
            arr.append(list(data.values())[1:])
    return arr
        
if __name__ == '__main__':
    # 测试一下能不能读取到数据
    print(read_json("register_login.json","img_code")) 

    # 读取的数据为:[[0.123, 200], [123, 200], ['', 404], ['123hello', 400]]
3️⃣参数化引用:parameterize

难点1:错误次数锁定

难点2: 查询登录状态,不同结果。

 【注意】由于parameterized的自身bug,运行测试用例必须是点击到测试用例所在的类名右键运行。如果想单独运行某个接口用例,则把其他接口代码先注释掉。

import unittest
from time import sleep

import requests

from api.api_register_login import ApiRegisterLogin

from parameterized import parameterized

from util import read_json


class TestRegisterLogin(unittest.TestCase):
    # 初始化
    def setUp(self) -> None:
        # 获取session对象
        self.session =requests.Session()
            # 获取ApiRegisterLogin实例
        self.reg = ApiRegisterLogin(self.session)


    # 结束
    def tearDown(self) -> None:
        # 关闭session对象
        self.session.close()

    #1、获取图片验证码接口 测试
    @parameterized.expand(read_json("register_login.json","img_code"))
    def test01_img_code(self,random,expect_code):
        try:
            # 调用图片验证码接口
            r = self.reg.api_img_code(random)
            # 查看响应状态码
            # print(r.status_code)
            self.assertEqual(expect_code,r.status_code)
        except Exception as err:
            # 日志
            print(err)
            # 抛异常
            raise

    #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、查看响应结果
            # print(r.json())
            self.assertIn(expec_text,r.text) # 使用text提取结果是更方便,json还要根据键找值
        except Exception as err:
            # 日志
            print(err)
            # 抛异常
            raise

    #3、注册接口 测试
    @parameterized.expand(read_json("register_login.json", "register"))
    def test03_register(self,phone,password,imgVerifyCode,phone_code,expec_text):
        try:
            # 1、图片验证码接口
            self.reg.api_img_code(234)
            # 2、短信验证码接口
            self.reg.api_phone_code(phone=phone, imgVerifyCode=imgVerifyCode)
            # 3、注册接口
            r = self.reg.api_register(phone=phone,password=password,verifycode=imgVerifyCode,phone_code=phone_code)
            # 4、查看结果
            # print(r.json())
            self.assertIn(expec_text,r.text)
        except Exception as err:
            # 日志
            print(err)
            # 抛异常
            raise

    #4、登录接口 测试
    @parameterized.expand(read_json("register_login.json", "login"))
    def test04_login(self,keywords,password,expec_text):
        try:
            i = 0
            r = None
            if "error" in password:
                while i <3:
                    r=self.reg.api_login(keywords,password)
                    i+=1
                # 锁定断言
                print("账号密码输错3次,账号锁定:",r.text)
                self.assertIn("锁定",r.text)
                # 暂停60秒
                sleep(60)
                r = self.reg.api_login(keywords=17612341111, password="win56")
                self.assertIn(expec_text,r.text)


            else:
                # 1、调用登录
                r = self.reg.api_login(keywords,password)
                # 2、查看结果
                # print(r.json())
                self.assertIn(expec_text, r.text)
        except Exception as err:
            # 日志
            print(err)
            # 抛异常
            raise

    #5、查询登录状态接口 测试
    @parameterized.expand(read_json("register_login.json", "login_status"))
    def test05_login_status(self,status,expec_text):
        try:
            if status == "已登录":
                # 调用登录擦口
                self.reg.api_login(keywords=17612341111, password="win56")
            # 调用查询登录状态接口
            r = self.reg.api_login_status()
            # 看结果
            # print(r.json())
            self.assertIn(expec_text, r.text)
        except Exception as err:
            # 日志
            print(err)
            # 抛异常
            raise

【总结】目前为止已经写的文件,文件内容上面均给出了代码

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

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

相关文章

Flink链接Kafka

一、基于 Flink 的 Kafka 消息生产者 Kafka 生产者的创建与配置&#xff1a; 代码通过 FlinkKafkaProducer 创建 Kafka 生产者&#xff0c;用于向 Kafka 主题发送消息。Flink 执行环境的配置&#xff1a; 配置了 Flink 的检查点机制&#xff0c;确保消息的可靠性&#xff0c;支…

基于国产麒麟操作系统,通过Kubeadm离线部署Kubernetes 1.28版本

文章目录 前言一、环境准备1.主机操作系统说明2.主机硬件配置3.ansible-playbook相关目录准备4.下载离线部署包4.1. 下载kubeclt、kubeam、kubelet RPM包4.2. 下载docker安装包4.3. 下载containerd安装包4.4. 镜像包下载 二、部署流程三、部署过程1.修改hosts文件2.部署单maste…

3、docker的数据卷和dockerfile

dockerfile--------------------自定义镜像 docker的数据卷&#xff1a; 容器与宿主机之间&#xff0c;或者容器和容器之间的数据共享&#xff08;目录&#xff09;。 创建容器的时间&#xff0c;通过指定目录&#xff0c;实现容器于宿主机之间&#xff0c;或者容器和容器之…

登上Nature!交叉注意力机制 发顶会流量密码!

在深度学习领域&#xff0c;交叉注意力融合技术正迅速崛起&#xff0c;并成为处理多模态数据的关键工具。这一技术通过有效地整合来自不同模态的信息&#xff0c;使得模型能够更好地理解和推理复杂的数据关系。 随着多模态数据的日益普及&#xff0c;如图像、文本和声音等&…

网安——CSS

一、CSS基础概念 CSS有两个重要的概念&#xff0c;分为样式和布局 CSS的样式分为两种&#xff0c;一种是文字的样式&#xff0c;一种是盒模型的样式 CSS的另一个重要的特质就是辅助页面布局&#xff0c;完成HTML不能完成的功能&#xff0c;比如并排显示或精确定位显示 从HT…

SOME/IP协议详解 基础解读 涵盖SOME/IP协议解析 SOME/IP通讯机制 协议特点 错误处理机制

车载以太网协议栈总共可划分为五层&#xff0c;分别为物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0c;传输层&#xff0c;应用层&#xff0c;其中今天所要介绍的内容SOME/IP就是一种应用层协议。 SOME/IP协议内容按照AUTOSAR中的描述&#xff0c;我们可以更进一步…

Mysql--实战篇--SQL优化(查询优化器,常用的SQL优化方法,执行计划EXPLAIN,Mysql性能调优,慢日志开启和分析等)

一、查询优化 1、查询优化器 (Query Optimizer) MySQL查询优化器&#xff08;Query Optimizer&#xff09;是MySQL数据库管理系统中的一个关键组件&#xff0c;负责分析和选择最有效的执行计划来执行SQL查询。查询优化器的目标是尽可能减少查询的执行时间和资源消耗&#xff…

CV项目详解:基于yolo8的车辆识别系统(含源码和具体教程)

使用YOLOv8&#xff08;You Only Look Once&#xff09;和OpenCV实现车道线和车辆检测&#xff0c;目标是创建一个可以检测道路上的车道并识别车辆的系统&#xff0c;并估计它们与摄像头的距离。该项目结合了计算机视觉技术和深度学习物体检测。 使用YOLOv8和OpenCV实现车道线…

osg中实现模型的大小、颜色、透明度的动态变化

以博饼状模型为对象,实现了模型大小、颜色、透明度的动态变化。 需要注意的是一点: // 创建材质对象osg::ref_ptr<osg::Material> material = new osg::Material;material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0.0, 1.0, 0.0, 0.5));// 获取模型的…

小米vela系统(基于开源nuttx内核)——openvela开源项目

前言 在 2024 年 12 月 27 日的小米「人车家全生态」合作伙伴大会上&#xff0c;小米宣布全面开源 Vela 操作系统。同时&#xff0c;OpenVela 项目正式上线 GitHub 和 Gitee&#xff0c;采用的是比较宽松的 Apache 2.0 协议&#xff0c;这意味着全球的开发者都可以参与到 Vela…

《数据思维》之数据可视化_读书笔记

文章目录 系列文章目录前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 数据之道&#xff0c;路漫漫其修远兮&#xff0c;吾将上下而求索。 一、数据可视化 最基础的数据可视化方法就是统计图。一个好的统计图应该满足四个标准&#xff1a;准确、有…

AI刷题-最大矩形面积问题、小M的数组变换

目录 一、最大矩形面积问题 问题描述 输入格式 输出格式 输入样例 输出样例 数据范围 解题思路&#xff1a; 问题理解 数据结构选择 算法步骤 最终代码&#xff1a; 运行结果&#xff1a; 二、小M的数组变换 问题描述 测试样例 解题思路&#xff1a; 问题…

数据库(MySQL)练习

数据库&#xff08;MySQL&#xff09;练习 一、练习1.15练习练习 二、注意事项2.1 第四天 一、练习 1.15练习 win11安装配置MySQL超详细教程: https://baijiahao.baidu.com/s?id1786910666566008458&wfrspider&forpc 准备工作&#xff1a; mysql -uroot -p #以管理…

C语言:-三子棋游戏代码:分支-循环-数组-函数集合

思路分析&#xff1a; 1、写菜单 2、菜单之后进入游戏的操作 3、写函数 实现游戏 3.1、初始化棋盘函数&#xff0c;使数组元素都为空格 3.2、打印棋盘 棋盘的大概样子 3.3、玩家出棋 3.3.1、限制玩家要下的坐标位置 3.3.2、判断玩家要下的位置是否由棋子 3.4、电脑出棋 3.4.1、…

知识图谱常见的主流图数据库

在知识图谱中&#xff0c;主流使用的图数据库包括以下几种&#xff1a; Neo4j&#xff1a;这是目前全球部署最广泛的图数据库之一&#xff0c;具有强大的查询性能和灵活的数据模型&#xff0c;适用于复杂关系数据的存储和查询。 JanusGraph&#xff1a;JanusGraph是一个开源的…

Nginx三种不同类型的虚拟主机(基于域名、IP 和端口)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; Nginx-从零开始的服务器之旅专栏&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年1月15日13点14分 目录 1. 基于域名的虚拟主机 …

RabbitMQ(四)

SpringBoot整合RabbitMQ SpringBoot整合1、生产者工程①创建module②配置POM③YAML④主启动类⑤测试程序 2、消费者工程①创建module②配置POM③YAML文件内配置&#xff1a; ④主启动类⑤监听器 3、RabbitListener注解属性对比①bindings属性②queues属性 SpringBoot整合 1、生…

java_将数据存入elasticsearch进行高效搜索

使用技术简介&#xff1a; (1) 使用Nginx实现反向代理&#xff0c;使前端可以调用多个微服务 (2) 使用nacos将多个服务管理关联起来 (3) 将数据存入elasticsearch进行高效搜索 (4) 使用消息队列rabbitmq进行消息的传递 (5) 使用 openfeign 进行多个服务之间的api调用 参…

win32汇编环境,对话框程序中组合框的应用举例

;运行效果 ;win32汇编环境,对话框程序中组合框的应用举例 ;比如在对话框中生成组合框&#xff0c;增加子项&#xff0c;删除某项&#xff0c;取得指定项内容等 ;直接抄进RadAsm可编译运行。重点部分加备注。 ;以下是ASM文件 ;>>>>>>>>>>>>…

occ的开发框架

occ的开发框架 1.Introduction This manual explains how to use the Open CASCADE Application Framework (OCAF). It provides basic documentation on using OCAF. 2.Purpose of OCAF OCAF (the Open CASCADE Application Framework) is an easy-to-use platform for ra…