【Unittest】Unittest接口测试框架开发-以登录模块为例

news2024/11/24 20:34:09

文章目录

    • 框架结构
    • 框架目录结构
    • 封装被测试系统接口
    • 定义接口测试用例
    • 集成测试报告
    • 测试数据参数化
      • (一)分析与数据构造
      • (二)基于JSON实现参数化
      • (三)基于数据库实现参数化

框架结构

框架结构包括:被测系统、API、数据库、TestCase、测试数据、测试报告。

(1)将测试用例TestCase与被测试系统API进行分离,便于后期维护。
(2)测试用例TestCase是通过unittest进行管理,并提供了丰富的断言(等于、包含等)。
(3)通过参数化思想测试数据与测试脚本的分离。
(4)调用数据库进行结果验证或将数据库作为参数化的数据源。
(5)借助第三方工具快速的生成HTML报告。

框架目录结构

  • data – 管理测试数据的文件夹
  • report – 管理测试结果报告的文件夹
  • api – 封装被测试系统的接口
  • scripts – 测试用例脚本
  • tools – 第三方工具包管理
  • app.py – 配置信息文件
  • run_suite.py – 测试用例执行入口
  • utils.py – 自定义工具类

在这里插入图片描述

封装被测试系统接口

在api包下新建login.py

# 封装被测试系统接口


# 定义接口类
class LoginAPI:

    # 初始化
    def __init__(self):
        self.url_login = "http://xxxlogin"

    # 登录接口
    def login(self, session, username, password):
        login_data = {
            "username": username,
            "password": password
        }
        return session.post(url=self.url_login, data=login_data)

定义接口测试用例

在script包下新建test01_login.py

# 导包
import requests
import unittest
from api.login import LoginAPI

# 定义测试类
class TestLoginAPI(unittest.TestCase):
    # 前置处理
    def setUp(self):
        self.login_api = LoginAPI()
        self.session = requests.Session()

    # 后置处理
    def tearDown(self):
        if self.session:
            self.session.close()

    # 定义测试方法
    
    # 登录成功
    def test01_login_success(self):
        # 调用登录接口
        response = self.login_api.login(self.session, "15588888888", "123456")
        print(response.json())
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, "登录成功", response.json().get("msg"))

    # 账号不正确
    def test02_user_isnot_exist(self):
        # 调用登录接口
        response = self.login_api.login(self.session, "13388888888", "123456")
        print(response.json())
        self.assertEqual(200, response.status_code)
        self.assertEqual(-1, response.json().get("status"))
        self.assertIn("账号不存在", response.json().get("msg"))
        
    # 密码错误
    def test03_password_exist(self):
        # 调用登录接口
        response = self.login_api.login(self.session, "13488888888", "error")
        print(response.json())
        self.assertEqual(200, response.status_code)
        self.assertEqual(-2, response.json().get("status"))
        self.assertIn("密码错误", response.json().get("msg"))

集成测试报告

将HTMLTestRunner.py放到tools包下
编辑run_suite.py

# 导包
import time
import unittest
from scripts.test01_login import TestLoginAPI
from tools.HTMLTestRunner import HTMLTestRunner

# 封装测试套件
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestLoginAPI))
# 指定报告路径
report = "./report/report-{}.html".format(time.strftime("%Y%m%d-%H%M%S"))
# 打开文件流
with open(report, "wb") as f:
  # 创建HTMLTestRunner执行器
  runner = HTMLTestRunner(f, title="接口测试报告")
  # 执行测试套件
  runner.run(suite)

测试数据参数化

(一)分析与数据构造

1、分析需要参数化的参数有哪些:
(1)输入数据:用户名、密码
(2)预期结果:content_type、状态码、业务码、业务消息
2、选择数据承载形式:
(1)json
(2)db
3、修改测试用例的代码:
(1)构建参数化数据(build_data方法)
(2)在测试用例前引用参数化(@parameterized装饰器)
(3)在具体的测试用例中,按照获得的数据进行参数替换

(二)基于JSON实现参数化

在data包下新建login.json

[
  {
    "desc": "case01 登录成功",
    "username": "15588888888",
    "password": "123456",
    "Content_Type": "image",
    "status-code": "200",
    "status": 1,
    "msg": "登录成功"
  },
  {
    "desc": "case02 账号不存在",
    "username": "13388888888",
    "password": "123456",
    "Content_Type": "image",
    "status-code": "200",
    "status": -1,
    "msg": "账号不存在"
  },
    {
    "desc": "case03 密码错误",
    "username": "15588888888",
    "password": "eroor",
    "Content_Type": "image",
    "status-code": "200",
    "status": -2,
    "msg": "密码错误"
  }
]

修改script包下test01_login.py的代码

# 导包
import json
import requests
import unittest
from api.login import LoginAPI
from parameterized import parameterized
# 构造测试数据
def build_data():
    json_file = "../data/login.json"
    test_data = []
    with open(json_file, encoding="utf-8") as f:
        json_data = json.load(f)
        for case_data in json_data:
            username = case_data.get("username")
            password = case_data.get("password")
            status_code = case_data.get("status_code")
            content_type = case_data.get("content_type")
            status = case_data.get("status")
            msg = case_data.get("msg")
            test_data.append((username, password, status_code,content_type, status, msg))
            print("test_data = {}".format((username, password, status_code, content_type, status, msg)))
            return test_data

# 定义测试类
class TestLoginAPI(unittest.TestCase):
    # 前置处理
    def setUp(self):
        self.login_api = LoginAPI()
        self.session = requests.Session()

    # 后置处理
    def tearDown(self):
        if self.session:
            self.session.close()
    # 定义测试方法
    @parameterized.expand(build_data)
    def test01_login(self, username, password, status_code,content_type, status, msg):
        # 调用登录接口
        response = self.login_api.login(self.session, username, password)
        print(response.json())
        self.assertEqual(status_code, response.status_code)
        self.assertEqual(status, response.json().get("status"))
        self.assertIn(msg, response.json().get("msg"))

(三)基于数据库实现参数化

修改script包下test01_login.py的代码

# 导包
import requests
import unittest
from api.login import LoginAPI
from tools.dbutil import DBUtil
from parameterized import parameterized
# 构造测试数据
def build_data():
    sql = "select * from t_login"
    db_data = DBUtil.exe_sql(sql)
    print(db_data)
    test_data = []
    for case_data in db_data:
        username = case_data[2]
        password = case_data[3]
        status_code = case_data[4]
        content_type = case_data[5]
        status = case_data[6]
        msg = case_data[7]
        test_data.append((username, password, status_code,content_type, status, msg))
        print("test_data = {}".format((username, password, status_code, content_type, status, msg)))
        return test_data

# 定义测试类
class TestLoginAPI(unittest.TestCase):
    # 前置处理
    def setUp(self):
        self.login_api = LoginAPI()
        self.session = requests.Session()

    # 后置处理
    def tearDown(self):
        if self.session:
            self.session.close()

    # 定义测试方法
    @parameterized.expand(build_data)
    def test01_login(self, username, password, status_code, content_type, status, msg):
        # 调用登录接口
        response = self.login_api.login(self.session, username, password)
        print(response.json())
        self.assertEqual(status_code, response.status_code)
        self.assertEqual(status, response.json().get("status"))
        self.assertIn(msg, response.json().get("msg"))

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

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

相关文章

Stable Diffusion:使用自己的数据集微调训练LoRA模型

Stable Diffusion:使用自己的数据集微调训练LoRA模型 前言前提条件相关介绍微调训练LoRA模型下载kohya_ss项目安装kohya_ss项目运行kohya_ss项目准备数据集生成关键词模型参数设置预训练模型设置文件夹设置训练参数设置 开始训练LoRA模型TensorBoard查看训练情况 测…

[JAVAee]Tomcat - Servlet

目录 Tomcat Servlet的工作 创建Servlet ①项目 ②依赖 ③目录 ④代码 ⑤打包 ⑥部署 ⑦验证 Servlet的运行原理 Servlet API HttpServlet 方法 处理Get/POST请求 HttpServletRequest 方法 获取请求中的信息 获取GET请求中的参数 获取POST请求中的参数…

基于YOLOv8模型和PCB电子线路板缺陷目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要:基于YOLOv8模型PCB电子线路板缺陷目标检测系统可用于日常生活中检测与定位PCB线路板瑕疵,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检…

Dbeaver安装与报错解决方案

官网 https://dbeaver.io/ Dbeaver :社区版,开源免费。 下载 下载地址(官网下载不了,在GitHub下载): https://github.com/dbeaver/dbeaver/releases 安装过程中的问题 双击安装包,按照提示…

第7步---MySQL的视图操作和

第7步---MySQL的视图操作 虚拟表。保存的只是视图的定义。不存放真实的数据,数据还是在原先的表中。 好处是方便和简化代码以及安全。 1.视图创建 数据准备 -- 创建表的测试数据 create table dept(deptno int primary key,dname varchar(20),loc varchar(20) ); …

基于Java+SpringBoot+vue前后端分离在线BLOG网站系统设计实现

基于JavaSpringBootvue前后端分离在线BLOG网站系统设计实现(程序源码毕业论文) 大家好,今天给大家介绍基于JavaSpringBootvue前后端分离在线BLOG网站系统设计与实现,本论文只截取部分文章重点,文章末尾附有本毕业设计完…

CPU缓存一致性原理

CPU缓存一致性原理 在本站的文章CPU缓存那些事儿中, 介绍了cpu的多级缓存的架构和cpu缓存行cache line的结构。CPU对于缓存的操作包含读和写,读操作在cache line中有所涉及,在本文中,将重点讨论CPU对于缓存进行写时的行为。 单核…

jmap(Memory Map for Java)Java内存映像工具

jmap(Memory Map for Java)Java内存映像工具 jmap(Memory Map for Java)命令用于生成堆转储快照(一般称为heapdump或dump文件) 如果不使用jmap命令,要想获取Java堆转储快照也还有一些比较“暴…

Linux -- 进阶 利用大文件来增加分区 自动挂载大文件

情景引入 : 比如, 你的硬盘 分了三个区,但是,现在就是要求要分第四个区, 你一看硬盘没有剩余空 间了,分不出第四个区了,除非你再添加 一块儿 新硬盘。 那就可以使用我们介绍的这种方法 &…

MyBatis入门配置及CURD实现

目录 一、MyBatis简介 1. 什么是 MyBatis ? 2. MyBatis的特性 3. 什么是持久层框架? 二、MyBatis环境配置 2.1 创建maven工程 2.2 导入相关pom依赖 2.3 导入jdbc配置文件 2.4 Mybatis相关插件安装 3.5 Mybatis-cfg.xml 核心配置 2.6 引入Log4j2日志文件…

【前缀和】算法实战

文章目录 一、算法原理1. 一维前缀和2. 二维前缀和 二、算法实战1. leetcode560 和为K的子数组2. leetcode974 和可被K整除的子数组3. leetcode525 连续数组4. leetcode1314 矩阵区域和5. leetcode724 寻找数组的中心下标6. leetcode238 除自身以外数组的乘积 三、总结 一、算法…

基于Python的高校学生成绩分析系统

随着计算机技术发展,计算机系统的应用已延伸到社会的各个领域,大量基于网络的广泛应用给生活带来了十分的便利。所以把高校成绩分析与现在网络相结合,利用计算机搭建高校成绩分析系统,实现高校成绩分析的信息化。则对于进一步提高…

gdb调试core dump

gdb调试core dump 文章目录 gdb调试core dumpgdb core dump调试步骤Segmentation faultcore dump**coredump文件的存储位置**apport手动指定存储位置 开启coredump测试readelf 查看core dump文件信息gdb查看core文件总结Reference>>>>> 欢迎关注公众号【三戒纪元…

P17~P18 电路定理 电路中难得的精彩到极致的电路理论

特勒根定理、互易定理、对偶定理比较难,非常重要,因为他们可以解决其他定理无法解决的问题。 1、特勒根定理1——个人感觉像能量守恒 特勒根定理与基尔霍夫定理齐名,与拓扑结构有关。都适用于任何线性非线性,时变的非时变的元件…

使用zoom预览出图和系统相机预览出图,画质不一样的问题分析

1、问题背景 最近在基于 Android 的平台调试一款摄像头,客户有反馈一个问题,系统自带的 Camera2 app 预览出图是正常的,但用 Zoom app 打开摄像头,出图画面存在畸变、锯齿、过曝的问题,现象如下图所示。 2、问题分析 …

前端基础(Web API)

目录 前言 Web API DOM 基本概念 查找元素 document.getElementById document.getElementsByClassName document.evaluate() 修改元素 添加元素 修改元素 复制元素 删除元素 Event事件 事件创建 常用的事件 监听事件 click事件 mouseover事件 事件绑定…

LTPP在线开发平台【使用教程】

LTPP在线开发平台 点击访问 LTPP在线开发平台 LTPP(Learning teaching practice platform)在线开发平台是一个编程学习网站,该网站集文章学习、短视频、在线直播、代码训练、在线问答、在线聊天和在线商店于一体,专注于提升用户编…

使用SpringBoot+SpringMVC+Mybatis+WebSocket实现云聊天项目

云聊天 1. 项目介绍 本项目是仿照微信实现网页版聊天程序,用户注册登录后可与在线好友实时聊天,下线好友上线后可以查看到好友发送的消息;用户可以在搜索框搜索用户添加好友;用户还可以查看好友申请列表,选择是否同意…

Golang使用消息队列(RabbitMQ)

最近在使用Golang做了一个网盘项目(类似百度网盘),这个网盘项目有一个功能描述如下:用户会删除一个文件到垃圾回收站,回收站的文件有一个时间期限,比如24h,24h后数据库中记录和oss中文件会被删除…

使用Vscode 编辑器 导出、导入和运行Excel中的VBA代码

使用Vscode 编辑器 导出、导入和运行Excel中的VBA代码 前言 Excel自带的 Microsoft Visual Basic for Applications 编辑器常被人称为上古编辑器,的确不适合代码编辑,这是其一,其二是当系统语言与Excel的安装语言不一致时,往往出现…