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

目录

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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【git】-3 github创建远程仓库,上传自己的项目,下载别人的项目

一、如何使用Github 1、创建远程仓库 2、使用github拉取/推送代码 克隆仓库 向远程仓库推送代码-git push 二、上传我们自己的项目到github 方法一&#xff1a;直接上传 方法二&#xff1a;使用git命令 方法三&#xff1a; 将仓库拉取到本地上传 三、下载别人的项目 …

Java算法 数据结构基础 并查集 模版 [洛谷-P3367]

目录 题目地址 题目描述 输入输出样例 并查集模版 介绍 1. 路径压缩&#xff08;Path Compression&#xff09; 2. 按秩合并&#xff08;Union by Rank / Size&#xff09; 代码讲解 操作讲解 时间复杂度分析 应用场景 题目地址 【模板】并查集 - 洛谷 题目描述 输…

PyCharm文档管理

背景&#xff1a;使用PyCharmgit做文档管理 需求&#xff1a;需要PyCharm自动识别docx/xslx/vsdx等文件类型&#xff0c;并在PyCharm内点击文档时唤起系统内关联应用(如word、excel、visio) 设置步骤&#xff1a; 1、file -》 settings -》file types 2、在Files opened i…

卷积神经05-GAN对抗神经网络

卷积神经05-GAN对抗神经网络 使用Python3.9CUDA11.8Pytorch实现一个CNN优化版的对抗神经网络 简单的GAN图片生成 CNN优化后的图片生成 优化模型代码对比 0-核心逻辑脉络 1&#xff09;Anacanda使用CUDAPytorch2&#xff09;使用本地MNIST进行手写图片训练3&#xff09;…

基于springboot的租房网站系统

作者&#xff1a;学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等 文末获取“源码数据库万字文档PPT”&#xff0c;支持远程部署调试、运行安装。 项目包含&#xff1a; 完整源码数据库功能演示视频万字文档PPT 项目编码&#xff1…

创建 WordPress 插件(第一部分):添加管理页面

WordPress 是互联网上最受欢迎的内容管理系统之一。它是用 PHP 创建的&#xff0c;可以处理从博客到商业网站的一切需求。事实上&#xff0c;我们的博客和网站都使用 WordPress。在本文中&#xff0c;我将向你展示如何创建一个 WordPress 插件&#xff0c;该插件会在管理员控制…

「港科技」联手「地平线」打造GPT风格的自动驾驶世界模型:DrivingWorld

摘要 最近在自回归&#xff08;AR&#xff09;生成模型方面的成功&#xff0c;例如自然语言处理中的GPT系列&#xff0c;激发了在视觉任务中复制这一成功的努力。一些研究尝试将这种方法扩展到自动驾驶中&#xff0c;通过构建基于视频的世界模型来生成逼真的未来视频序列和预测…

FPGA工程师成长四阶段

朋友&#xff0c;你有入行三年、五年、十年的职业规划吗&#xff1f;你知道你所做的岗位未来该如何成长吗&#xff1f; FPGA行业的发展近几年是蓬勃发展&#xff0c;有越来越多的人才想要或已经踏进了FPGA行业的大门。很多同学在入行FPGA之前&#xff0c;都会抱着满腹对职业发…

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

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

为ARM64架构移植Ubuntu20.04换源的发现

在为ARM64架构(RK3566)移植ubuntu20.04的时候发现在更换为国内源之后&#xff0c;无法正常完成apt update,报错为: Ign:25 http://mirrors.aliyun.com/ubuntu focal-updates/main arm64 Packages …

Playwright vs Selenium:全面对比分析

在现代软件开发中&#xff0c;自动化测试工具在保证应用质量和加快开发周期方面发挥着至关重要的作用。Selenium 作为自动化测试领域的老牌工具&#xff0c;长期以来被广泛使用。而近年来&#xff0c;Playwright 作为新兴工具迅速崛起&#xff0c;吸引了众多开发者的关注。那么…

【全套】基于机器学习的印度森林火灾发生概率的分析与预测

【私信送源码文档】基于机器学习的印度森林火灾发生概率的分析与预测 对应的ppt 摘 要 随着全球气候变化的不断加剧&#xff0c;火灾的频发和规模逐渐增大&#xff0c;成为备受关注的问题。本文旨在提高对火灾发生概率的准确性&#xff0c;为火灾的预防和管理提供科学支持。在…

【Go】Go Gin框架初识(一)

1. 什么是Gin框架 Gin框架&#xff1a;是一个由 Golang 语言开发的 web 框架&#xff0c;能够极大提高开发 web 应用的效率&#xff01; 1.1 什么是web框架 web框架体系图&#xff08;前后端不分离&#xff09;如下图所示&#xff1a; 从上图中我们可以发现一个Web框架最重要…

TCP/IP协议簇及封装与解封装

TCP/IP协议簇 现如今用的参考模型TCP/IP 是一个协议簇&#xff0c;它组建了整个互联网 最主要的是TCP/IP 和这两个协议&#xff0c;所以起名为TCP/IP TCP/IP模型 TCP/IP标准模型——四层 TCP/IP对等模型——五层 数据链路层分为两个子层&#xff1a; LLC子层&#xff1a;逻辑…

《基于卷积神经网络的星图弱小目标检测》论文精读

Dim small target detection based on convolutinal neural network in star image 摘要 由于低信噪比目标和复杂背景&#xff0c;星图中弱小目标的检测是一项具有挑战性的任务。本文提出了一种深度学习方法&#xff0c;用于在背景不均匀和不同类型的噪声下检测单帧星图中的弱…

如何选择Ubuntu版本

一、为什么要选择Ubuntu系统&#xff1f; CentOS官方已全面停止维护CentOS Linux项目 。具体来说&#xff0c;CentOS 8已于2021年12月31日停止维护&#xff0c;而CentOS 7则在2024年6月30日结束了生命周期 。这意味着这些版本不再接收官方的安全更新、bug修复或技术支持 二、…

计算机视觉算法实战——视频分析(Video Analysis)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​​​​ ​​​​​​​​​​​​ ​​​​​ 视频分析是计算机视觉中的一个重要领域&#xff0c;旨在从视频数据中提取有用的信息&…

O2O同城系统架构与功能分析

2015工作至今&#xff0c;10年资深全栈工程师&#xff0c;CTO&#xff0c;擅长带团队、攻克各种技术难题、研发各类软件产品&#xff0c;我的代码态度&#xff1a;代码虐我千百遍&#xff0c;我待代码如初恋&#xff0c;我的工作态度&#xff1a;极致&#xff0c;责任&#xff…

讲一下ZooKeeper的持久化机制?

大家好&#xff0c;我是锋哥。今天分享关于【讲一下ZooKeeper的持久化机制&#xff1f;】面试题。希望对大家有帮助&#xff1b; 讲一下ZooKeeper的持久化机制&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 ZooKeeper 是一个开源的分布式协调服务&…

C++ 文字识别OCR

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…