【Unittest】Requests实现小程序项目接口测试

news2025/1/12 12:14:05

文章目录

    • 一、搭建接口测试框架
    • 二、初始化日志
    • 三、定义全局变量
    • 四、封装接口
    • 五、编写测试用例
    • 六、生成测试报告

一、搭建接口测试框架

目录结构如下。

在这里插入图片描述

二、初始化日志

在utils.py文件中编写如下如下代码,初始化日志。

# 导入app.py全局变量文件
import app
import logging
from logging import handlers

# 定义初始化日志的函数
def init_logging():
    # 创建日志器
    logger = logging.getLogger()
    # 设置日志等级
    logger.setLevel(logging.INFO)
    # 创建控制台处理器
    sh = logging.StreamHandler()
    # 创建文件处理器
    fh = logging.handlers.TimedRotatingFileHandler(app.BASE_DIR+"/log/mimi.log",
                                                   when='M',
                                                   interval=5,
                                                   backupCount=3,
                                                   encoding='utf-8')
    # 定义日志的格式(格式化器)
    fmt = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
    formatter = logging.Formatter(fmt)
    # 将格式化器添加到处理器
    sh.setFormatter(formatter)
    fh.setFormatter(formatter)
    # 将处理器添加到日志器当中
    logger.addHandler(sh)
    logger.addHandler(fh)

在api下的init.py文件中编写如下代码,进行实际的初始化日志。

# 导入utils.py中编写的初始化日志的函数和logging模块
# 然后调用初始化日志的函数
# 最后测试日志是不是能够打印

# 导包
import utils
import logging

# 初始化日志
utils.init_logging()

# 使用logging模块打印日志
logging.info("Test初始化日志后能不能打印日志")

三、定义全局变量

在app.py文件中编写如下代码,定义全局变量。

# 1 测试项目接口的代码项目地址
import os

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
print(BASE_DIR)
# 2 测试项目服务器的根URL
BASE_URL = "http://www.nidexiangmu.com:13140"
# 3 Token(令牌,维持登录状态)
TOKEN = "bd8f3599604107c0d7eebe1ffe15d84a"
# 4 HEADERS(请求一般都是固定的)
HEADERS = {"Content-Type":"application/json", "token": TOKEN}
# 5 Code(由微信小程序前端生成,用于发送给服务器,来获取token)
CODE = "023tA6DW1eYZoY0g0JzW1bY5DW1tA6DK"

四、封装接口

在api下创建ego_api.py项目,根据API文档编写如下格式的代码,封装所有待测试接口。

# 导入requests模块
import requests
import app
# 创建API接口类
class EgoApi:

    def __init__(self):
        # 定义轮播图的url
        self.banner_url = app.BASE_URL + "/api/v1/banner/1"
        # 定义专题栏位的url
        self.theme_url = app.BASE_URL + "/api/v1/theme"
        # 最近新品的URL
        self.recent_product_url = app.BASE_URL + "/api/v1/product/recent"
        # 获取商品分类url
        self.category_url = app.BASE_URL + "/api/v1/category/all"
        # 获取商品分类下的某个商品
        self.by_category_url = app.BASE_URL + "/api/v1/product/by_category"
        # 获取商品详情
        self.product_detail_url = app.BASE_URL + "/api/v1/product"
        # 获取用户订单列表
        self.order_list_url = app.BASE_URL + "/api/v1/order/by_user"
        # 创建订单URL
        self.create_order_url = app.BASE_URL + "/api/v1/order"
        # 查看订单详情
        self.order_detail_url = app.BASE_URL + "/api/v1/order"
        # 获取Token
        self.get_token_url = app.BASE_URL + "/api/v1/token/user"
        # 验证token的url
        self.verify_token_url = app.BASE_URL + "/api/v1/token/verify"
        # 获取地址信息的URL
        self.get_address_url = app.BASE_URL + "/api/v1/address"
    # 轮播图
    def get_banner(self):
        return requests.get(self.banner_url)

    # 专题栏位
    def theme(self, params):
        return requests.get(self.theme_url, params={"ids":params})

    # 最近新品
    def recent_product(self):
        return requests.get(self.recent_product_url)

    # 获取商品分类
    def get_product_category(self):
        return requests.get(self.category_url)

    # 获取商品分类下的某个商品
    def by_category(self, params):
        return requests.get(self.by_category_url, params={"id":params})

    # 获取商品信息
    def get_product_detail(self, product_id):
        return requests.get(self.product_detail_url + "/" + str(product_id))

    # 获取用户订单列表(登录后的接口)
    def get_order_list(self, page):
        return requests.get(self.order_list_url, params={"page":page}, headers=app.HEADERS)

    # 创建订单
    def create_order(self, jsondata):
        return requests.post(self.create_order_url, json=jsondata, headers=app.HEADERS)

    # 查看订单
    def get_order_detail(self, order_id):
        return requests.get(self.order_detail_url + "/" + str(order_id), headers=app.HEADERS)

    # 获取Token
    def get_token(self, code):
        return requests.post(self.get_token_url, json={"code": code})

    # Token验证接口
    def verify_token(self, token):
        return requests.post(self.verify_token_url, json={"token": token})

    # 获取地址信息
    def get_address(self):
        return requests.get(self.get_address_url, headers=app.HEADERS)

五、编写测试用例

在script下创建test_ego.py文件,根据接口测试用例文档编写测试代码,以下代码为正向测试用例示例。

import unittest
import logging
import app
from api.ego_api import EgoApi

class TestEgo(unittest.TestCase):

    def setUp(self):
        # 手动设置token
        app.HEADERS["token"] = ""

    @classmethod
    def setUpClass(cls):
        cls.ego_api = EgoApi()

    def test01_get_banner_success(self):
        # 使用实例化的ego_api发送获取轮播图的接口请求
        response = self.ego_api.get_banner()
        # 打印响应数据
        logging.info("正向用例获取轮播图的测试结果为:{}".format(response.json()))
        # 断言结果
        self.assertEqual(200, response.status_code)
        self.assertEqual("首页轮播图", response.json().get("description"))

    def test02_get_theme_success(self):
        response = self.ego_api.theme("1,2,3")
        logging.info("正向用例获取专题栏位的测试结果为:{}".format(response.json()))
        self.assertEqual(200, response.status_code)
        self.assertEqual("专题栏位一", response.json()[0].get("name"))

    def test03_get_recent_product(self):
        response = self.ego_api.recent_product()
        logging.info("测试获取最近新品接口:{}".format(response.json()))
        self.assertEqual(200, response.status_code)
        self.assertEqual("芹菜 半斤", response.json([0].get("name")))

    def test04_get_product_category(self):
        response = self.ego_api.get_product_category()
        logging.info("测试获取商品分类接口:{}".format(response.json()))
        self.assertEqual(200, response.status_code)
        self.assertEqual("果味", response.json([0].get("name")))

    # 获取商品分类下的商品
    def test05_get_product(self):
        # 使用封装的接口获取商品分类下的商品
        response = self.ego_api.by_category(2)
        # 打印结果
        logging.info("获取商品分类下的商品为:{}".format(response.json()))

        # 断言
        self.assertEqual(200, response.status_code)
        self.assertEqual("梨花带雨 3个", response.json()[0].get("name"))

    # 获取商品详情
    def test06_get_product_detail(self):
        # 使用封装的接口获取商品详情
        response = self.ego_api.get_product_detail(2)
        # 打印结果
        logging.info("获取商品商品详情:{}".format(response.json()))

        # 断言
        self.assertEqual(200, response.status_code)
        self.assertEqual("梨花带雨 3个", response.json().get("name"))

六、生成测试报告

在run_suite.py文件中编写如下代码,可生成测试报告。

# 导包
import unittest
import app
from script.test_ego import TestEgo
from lib.HTMLTestRunner import HTMLTestRunner
# 创建测试套件
suite = unittest.TestSuite()
# 将测试用例的代码添加到测试套件中
suite.addTest(unittest.makeSuite(TestEgo))
# 定义测试报告的路径和名称
report_name = app.BASE_DIR + "/report/mini.html"
# 使用HTMLTestRunner运行测试套件生成测试报告
with open(report_name, 'wb') as f:
    # 初始化HTMLTestRunner
    runner = HTMLTestRunner(f, verbosity=1, title="Ego微商", description="测试Ego微商的常见接口")
    # 使用实例化的runner运行测试套件,并生成测试报告
    runner.run(suite)

七、运行结果

1、日志结果如下:

在这里插入图片描述

2、测试报告结果如下(生成的测试报告位于report文件夹下):

在这里插入图片描述

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

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

相关文章

基于Zookeeper搭建Kafka高可用集群(实践可用)

目录 一、Zookeeper集群搭建 1.1 下载 & 解压 1.2 修改配置 1.3 标识节点 1.4 启动集群 1.5 集群验证 二、Kafka集群搭建 2.1 下载解压 2.2 拷贝配置文件 2.3 修改配置 2.4 启动集群 2.5 创建测试主题 2.6 写入数据测试 一、Zookeeper集群搭建 为保证集群高可…

SV中的随机化约束

1.多个变量相互依赖,如何进行随机化? 采用solve before (1)constraint c_valid_write_data {solve access_type before data;solve burst_length before data;(access_type TVIP_AXI_WRITE_ACCESS) -> data.size() burst…

算法通过村第五关-队列和Hash黄金笔记|LRU的设计与实现

文章目录 前言1. LRU的含义2. Hash双向链表实现LRU总结 前言 提示:我曾如此渴望命运的波澜,到最后才发现:人生最曼妙的风景,竟是内心的淡定从容。 我们层如此盼望世界的认可,到最后才知道:世界是自己&#…

01-Kafaka

1、Kafka 2 的安装与配置 1、上传kafka_2.12-1.0.2.tgz到服务器并解压: tar -zxf kafka_2.12-1.0.2.tgz -C /opt 2、配置环境变量并更新: 编辑profile配置文件: vim /etc/profile #设置kafka的环境变量export KAFKA_HOME/opt/kafka_2.1…

【ESP32--FreeRTOS 任务间的同步与通信】

本文主要记录【ESP32–FreeRTOS 任务间的同步与通信】的学习记录,邮件,信号量,事件组的使用和优缺点以及应用场景 📋 个人简介 💖 作者简介:大家好,我是喜欢记录零碎知识点的小菜鸟。&#x1f6…

软件测试之随机测试

目录 一、作随机测试之前的一些前提条件 二、随机测试功能点的选取 三、功能点的随机测试 在软件测试中除了根据测试用例和测试说明书进行功能测试外,还需要进行随机测试(Ad-hoc testing),随机测试是没有书面测试用例、记录期望…

【算法】插入排序

插入排序 插入排序代码实现代码优化 排序: 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录&…

【算法】归并排序 详解

归并排序 详解 归并排序代码实现1. 递归版本2. 非递归版本 排序: 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性: 假定在待排序的记录序列中,存在多个具有相…

dpkt 处理linux cooked capture

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

CUDA小白 - NPP(4) 图像处理 Data Exchange and Initialization(1)

cuda小白 原始API链接 NPP GPU架构近些年也有不少的变化,具体的可以参考别的博主的介绍,都比较详细。还有一些cuda中的专有名词的含义,可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》 常见的NppStatus&#xf…

QT 初识多线程

1.QThread线程基础 QThread是Qt线程中有一个公共的抽象类,所有的线程类都是从QThread抽象类中派生的,需要实现QThread中的虚函数run(),通过start()函数来调用run函数。 void run()函数是线程体函数,用于定义线程的功能…

借助CIFAR10模型结构理解卷积神经网络及Sequential的使用

CIFAR10模型搭建 CIFAR10模型结构 0. input : 332x32,3通道32x32的图片 --> 特征图(Feature maps) : 3232x32即经过32个35x5的卷积层,输出尺寸没有变化(有x个特征图即有x个卷积核。卷积核的通道数与输入的通道数相等,即35x5&am…

01-从JDK源码级别剖析JVM类加载机制

1. 类加载运行全过程 当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载器把主类加载到JVM。 public class Math {public static final int initData 666;public static User user new User();public int compute() { //一个方法对应一块栈帧…

整理mongodb文档:事务(一)

个人博客 整理mongodb文档:事务(一) 原文链接,个人博客 求关注,本文主要讲下怎么在mongose下使用事务,建议电脑端看 文章概叙 本文的开发环境为Nodejs,在‘单机模式’讲解最基本的事务概念。并没有涉及分片以及集群&#xff0…

《向量数据库指南》——AI原生向量数据库Milvus Cloud 2.3新功能

New Feature Upsert 功能 支持用户通过 upsert 接口更新或插入数据。已知限制,自增 id 不支持 upsert;upsert 是内部实现是 delete + insert所以性能上会有一定损耗,如果明确知道是写入数据的场景请继续使用 insert。 Range Search 功能 支持用户通过输入参数指定 search 的…

TortoiseGit设置作者信息和用户名、密码存储

前言 Git 客户端每次与服务器交互,都需要输入密码,但是我们可以配置保存密码,只需要输入一次,就不再需要输入密码。 操作说明 在任意文件夹下,空白处,鼠标右键点击 在弹出菜单中按照下图点击 依次点击下…

LLVM 与代码混淆技术

项目源码 什么是 LLVM LLVM 计划启动于2000年,开始由美国 UIUC 大学的 Chris Lattner 博士主持开展,后来 Apple 也加入其中。最初的目的是开发一套提供中间代码和编译基础设施的虚拟系统。 LLVM 命名最早源自于底层虚拟机(Low Level Virtu…

LEARN GIT

概念 基础概念 本地电脑 代码区:工作区间,放代码的地方 暂存区:git所管理的暂存区域 本地仓库:git所管理的本机的硬盘区域 远程电脑 远程仓库:github、gitee 代码提交管理的过程 代码区------->暂存区-------&…

关于 RK3568的linux系统killed用户应用进程(用户现象为崩溃) 的解决方法

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/132710642 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

模拟Proactor模式实现 I/O 处理单元

编写main.cpp 1.socket通信 服务器应用程序可以通过读取和写入 Socket 对象 来监听来自客户端的请求并向客户端返回响应 #define MAX_FD 65536 // 最大的文件描述符个数 #define MAX_EVENT_NUMBER 10000 // 监听的最大的事件数量 // 添加信号捕捉 void addsig(int sig, …