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

文章目录

    • 框架结构
    • 框架目录结构
    • 封装被测试系统接口
    • 定义接口测试用例
    • 集成测试报告
    • 测试数据参数化
      • (一)分析与数据构造
      • (二)基于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.rhkb.cn/news/98276.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

取证的学习

Volatility命令语法 1.判断镜像信息,获取操作系统类型 Volatility -f xxx.vmem imageinfo 在查到操作系统后如果不确定可以使用以下命令查看 volatility - f xxx.vmem --profile [操作系统] volshell 2.知道操作系统类型后,用–profile指定 volat…

后端开发12.商品模块

概述 简介 商品模块这个设计的非常复杂 效果图 数据库

Go语言基础之基本数据类型

Go语言中有丰富的数据类型,除了基本的整型、浮点型、布尔型、字符串外,还有数组、切片、结构体、函数、map、通道(channel)等。Go 语言的基本类型和其他语言大同小异。 基本数据类型 整型 整型分为以下两个大类: 按…

LeetCode 1162. As Far from Land as Possible【多源BFS】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

Qt快速学习(一)--对象,信号和槽

目录 1.Qt概述 1.1 什么是Qt 2.2 手动创建 2.3 pro文件 2.4 一个最简单的Qt应用程序 3 第一个Qt小程序 3.1 按钮的创建 3.2 对象模型(对象树) 3.3 Qt窗口坐标体系 4 信号和槽机制 4.1 系统自带的信号和槽 4.2 自定义信号和槽 4.3信号槽的拓展 4…

mac录屏工具,录屏没有声音的解决办法

mac录屏工具,录屏没有声音的解决办法 在使用macbook录制屏幕时,发现自带的录屏工具QuickTime Player没有声音,于是尝试了多款录屏工具,对其做一些经验总结(省流:APP Store直接可以免费下载使用Omi录屏专家…

【深度学习 | 感知器 MLP(BP神经网络)】掌握感知的艺术: 感知器和MLP-BP如何革新神经网络

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

2023年网络安全比赛--综合渗透测试(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 1.扫描目标靶机将靶机开放的所有端口,当作flag提交(例:21,22,23); 2.扫描目标靶机将靶机的http服务版本信息当作flag提交(例:apache 2.3.4); 3.靶机网站存在目录遍历漏洞,请将…

《合成孔径雷达成像算法与实现》Figure3.12

clc clear close all% 参数设置 TBP 724; % 时间带宽积 T 42e-6; % 脉冲持续时间 t_0 1e-6; % 脉冲回波时延 Nfft 2^11; % fft长度% 参数计算 B TBP/…

Flink状态和状态管理

1.什么是状态 官方定义:当前计算流程需要依赖到之前计算的结果,那么之前计算的结果就是状态。 这句话还是挺好理解的,状态不只存在于Flink,也存在生活的方方面面,比如看到一个认识的人,如何识别认识呢&am…

Springboot 实践(10)spring cloud 与consul配置运用之服务的注册与发现

前文讲解,完成了springboot、spring security、Oauth2.0的继承,实现了对系统资源的安全授权、允许获得授权的用户访问,也就是实现了单一系统的全部技术开发内容。 Springboot是微服务框架,单一系统只能完成指定系统的功能&#xf…

NLP序列标注问题,样本不均衡怎么解决?

【学而不思则罔,思而不学则殆】 1.问题 NLP序列标注问题,样本不均衡怎么解决? 2.解释 以命名实体识别(NER)为例,这个样本不均衡有两种解释: (1)实体间类别数量不均衡…

MNN学习笔记(八):使用MNN推理Mediapipe模型

1.项目说明 最近需要用到一些mediapipe中的模型功能,于是尝试对mediapipe中的一些模型进行转换,并使用MNN进行推理;主要模型包括:图像分类、人脸检测及人脸关键点mesh、手掌检测及手势关键点、人体检测及人体关键点、图像嵌入特征…

JVM编译优化

即时编译器 HotSpot虚拟机中内置了两个即时编译器,分别称为Client Compiler和Server Compiler,或者简称为C1编译器和C2编译器。Java8默认开启Server模式。用户可以使用“-client”或“-server”参数去指定编译模式。 C1编译器启动速度快,关注局部简单可靠的优化,比如方法…

Android glide框架及框架涉及到的设计模式

目录 原文链接Android glide框架 简单使用介绍Glide 框架整体结构设计Glide 框架的优点基本使用:Glide占位符 Android glide框架涉及到的设计模式 原文链接 Android glide框架 简单使用介绍 Glide:快速高效的Android图片加载库,可以自动加载…

【100天精通python】Day38:GUI界面编程_PyQt 从入门到实战(中)_数据库操作与多线程编程

目录 专栏导读 4 数据库操作 4.1 连接数据库 4.2 执行 SQL 查询和更新: 4.3 使用模型和视图显示数据 5 多线程编程 5.1 多线程编程的概念和优势 5.2 在 PyQt 中使用多线程 5.3 处理多线程间的同步和通信问题 5.3.1 信号槽机制 5.3.2 线程安全的数据访问 Q…

更新arm的linux编译工具链

虑到目前arm的gcc 5.5的工具链对C17语法支持不足,需要升级下工具链。 以下是详细步骤。使用官方提供的工具链 ARM官方的工具链网站: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads bare-metal这个版本就是没有操作系统(裸机环…

QChart类用来 管理 图表的:数据序列(series)、图例(legend)和坐标轴(axis)

QChart类用来 管理 图表的:数据序列(series)、图例(legend)和坐标轴(axis) 1、数据序列类 继承关系 2、坐标轴类 的继承关系 3、图例类 什么是图例? 图例:是集中于地图…

06_布隆过滤器BloomFilter_副本

06——布隆过滤器BloomFilter 一、是什么 由一个初始值都为零的bit数组和多个哈希函数构成,用来快速判断集合中是否存在某个元素 设计思想: 1. 目的:减少内存占用 1. 方式:不保存数据信息,只是在内存中做一个是否存…

Labview选项卡之实现被选择选项卡工作

文章目录 前言一、使用选项卡二、实现被选择选项卡工作1、需求2、分析3、实现①、前面板②、程序框图 三、效果展示四、源码自取 前言 有些时候,我们做界面,需要好多个界面切换。如果是同一个 VI 里界面切换,一般都是选项卡了。切换不同选项…