Python+Requests-2-接口自动化脚本实现(虫师-Django接口测试实例)

2023-11-17

编写脚本前分析项目架构

需求:python脚本实现【添加发布会信息】的接口测试,以邮件形式发送测试报告

1.新建一个case目录,存放测试用例

2.新建一个config目录,存放配置信息和读取配置信息

3.新建一个db_fixture目录,初始化数据

4.新建report目录,用来存放生成的测试报告

5.run_main.py文件,执行接口测试脚本

(一般还会新建一个common目录,存放一些公共方法,例如读取excel方法等)

 

编写脚本

1.config部分

(1)db_config.ini 数据库配置信息(此处需注意,这里的数据库需要与实际项目的数据库一致)

# coding:utf-8
# 数据库配置信息

[mysqlconf]
host = 47.xx.xxx.xx
port = 3306
user = root
password = 123456
db = guest

 

(2) readDbConfig.py 读取数据库信息,封装清除数据和插入数据的方法,以便进行初始化数据的操作

#coding:utf-8

from pymysql import connect,cursors
from pymysql.err import OperationalError
import os
import configparser

# ================读取db_config.ini文件设置=================


cur_path = os.path.dirname(os.path.realpath(__file__))
configPath = os.path.join(cur_path,"db_config.ini")
cf = configparser.ConfigParser()
cf.read(configPath,encoding='UTF-8')

host = cf.get("mysqlconf","host")
port = cf.get("mysqlconf","port")
db = cf.get("mysqlconf","db")
user = cf.get("mysqlconf","user")
password = cf.get("mysqlconf","password")


# ================封装MySQL基本操作=================
class DB:
    def __init__(self):
        try:
            # 连接数据库
            self.conn = connect(
                host = host,
                user = user,
                password = password,
                db = db,
                charset = "utf8mb4",
                cursorclass = cursors.DictCursor
                )
        except OperationalError as e:
            print("Mysql Error %d:%s"%(e.args[0],e.args[1]))

    # 清除表数据
    def clear(self,tabel_name):
        real_sql = "delete from "+ tabel_name +";"
        with self.conn.cursor() as cursor:
            cursor.execute("SET FOREIGN_KEY_CHECKS = 0;")
            cursor.execute(real_sql)
        self.conn.commit()

    # 插入表数据
    def insert(self,table_name,table_data):
        for key in table_data:
            table_data[key] = "'"+str(table_data[key])+"'"
        key = ','.join(table_data.keys())
        value = ",".join(table_data.values())
        real_sql = "INSERT INTO " + table_name + " (" + key + ") VALUES (" + value +")" + ";"
        print(real_sql)
        with self.conn.cursor() as cursor:
            cursor.execute(real_sql)
        self.conn.commit()

    # 关闭数据库连接
    def close(self):
        self.conn.close()

if __name__ == '__main__':
    db = DB()
    table_name = "sign_event"
    data = {"id":12,
            "name":"红米",
            "limit2":2000,
            "status":1,
            "address":"北京会展中心",
            "start_time":"2018-10-30 08:00:00",
            }
    db.clear(table_name)
    db.insert(table_name,data)
    db.close()

 

(3) email_config.ini 邮箱信息

# coding:utf-8
# 邮箱配置信息

[email]
smtp_server = smtp.qq.com
port = 465
sender = 907xxxx@qq.com
psw = xxxxxxxx
receiver = 2092xxxxx@qq.com

 

(4) readEmailConfig.py 读取邮件信息

#coding:utf-8

# ================读取cfg.ini文件设置=================

import os
import configparser

# os.path.realpath(__file__):返回当前文件的绝对路径
# os.path.dirname(): 返回()所在目录
cur_path = os.path.dirname(os.path.realpath(__file__)) # 当前文件的所在目录
configPath = os.path.join(cur_path,"email_config.ini") # 路径拼接:/config/email_config.ini
conf = configparser.ConfigParser()
conf.read(configPath,encoding='UTF-8') # 读取/config/email_config.ini 的内容

# get(section,option) 得到section中option的值,返回为string类型
smtp_server = conf.get("email","smtp_server")
sender = conf.get("email","sender")
psw = conf.get("email","psw")
receiver = conf.get("email","receiver")
port = conf.get("email","port")

2.db_fixture部分

(1)test_data.py 添加测试数据

# coding:utf-8

from config.readDbConfig import DB
# 创建测试数据
datas = {
    # 发布会表数据
    "sign_event":[
        {"id":1,"name":"红米Pro发布会","limit2":2000,"status":1,"address":"北京会展中心","start_time":"2018-10-31 08:00:00"},
        {"id":2,"name":"可参加人数为0","limit2":0,"status":1,"address":"北京会展中心","start_time":"2018-10-31 08:00:00"},
        {"id":3,"name":"当前状态为0关闭","limit2":2000,"status":0,"address":"北京会展中心","start_time":"2018-10-31 08:00:00"},
        {"id":4,"name":"发布会已结束","limit2":2000,"status":1,"address":"北京会展中心","start_time":"2017-10-31 08:00:00"},
        {"id":5,"name":"小米5发布会","limit2":2000,"status":1,"address":"北京会展中心","start_time":"2018-10-31 08:00:00"}
    ]
}

# 将测试数据插入表
def init_data():
    db = DB()
    for table,data in datas.items():
        db.clear(table)
        for d in data:
            db.insert(table,d)
    db.close()

if __name__ == '__main__':
    init_data()

 

3.case部分

(1)test_add_event.py 测试用例

# coding:utf-8
import unittest
import requests
import os,sys

cur_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,cur_path)
from db_fixture import test_data

class TestAddEvent(unittest.TestCase):
    """添加发布会"""
    def setUp(self):
        self.base_url = "http://47.xx.xxx.xx:8000/api/add_event/"

    def tearDown(self):
        print("")

    def test_add_event_all_null(self):
        """所有参数为空添加"""
        payload = {"eid":"","name":"","limit2":"","address":"","start_time":""}
        r = requests.post(self.base_url,data=payload)
        self.result = r.json()
        self.assertEqual(self.result["status"],10021)
        self.assertEqual(self.result["message"],"parameter error")

    def test_add_event_eid_exist(self):
        """id已经存在"""
        payload = {"eid":1,"name":"一加4发布会","limit2":2000,"address":"深圳宝体","start_time":"2018-11-01 08:00:00"}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        self.assertEqual(self.result["status"], 10022)
        self.assertEqual(self.result["message"], "event id already exists")

    def test_add_event_name_exists(self):
        """名称已经存在"""
        payload = {"eid": 88, "name": "红米Pro发布会", "limit2": 2000, "address": "深圳宝体", "start_time": "2018-11-01 08:00:00"}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        self.assertEqual(self.result["status"], 10023)
        self.assertEqual(self.result["message"], "event name already exists")

    def test_add_event_data_type_error(self):
        """日期格式错误"""
        payload = {"eid": 102, "name": "一加4发布会", "limit2": 2000, "address": "深圳宝体", "start_time": "2018"}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        self.assertEqual(self.result["status"], 10024)


    def test_add_event_success(self):
        """添加成功"""
        payload = {"eid": 88, "name": "孙小二发布会", "limit2": 2000, "address": "深圳宝体", "start_time": "2018-11-01 08:00:00"}
        r = requests.post(self.base_url, data=payload)
        self.result = r.json()
        print(self.result)
        self.assertEqual(self.result["status"], 200)


if __name__ == '__main__':
    test_data.init_data() # 初始化接口测试数据
    unittest.main()

 

4.run_main.py 执行脚本

# coding:utf-8
import os
import unittest
import time
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from db_fixture import test_data
import HTMLTestRunnerCN_test
from config import readEmailConfig

# 当前脚本所在文件真实路径
cur_path = os.path.dirname(os.path.realpath(__file__))

def add_case(caseName="case",rule="test_*.py"):
    """第一步:加载所有测试用例"""
    case_path = os.path.join(cur_path,caseName) # 用例文件夹
    # 文件夹不存在就创建一个文件夹
    if not os.path.exists(case_path):os.mkdir(case_path)

    # 定义discover加载所有测试用例
    # case_path:执行用例的目录;pattern:匹配脚本名称的规则;top_level_dir:默认为None
    discover = unittest.defaultTestLoader.discover(case_path,pattern=rule,top_level_dir=None)
    return discover

def run_case(all_case,reportName="report"):
    """第二步:执行所有的用例,并把结果写入到html测试报告中"""
    now = time.strftime("%Y_%m_%d_%H_%M_%S")
    report_path = os.path.join(cur_path,reportName)
    if not os.path.exists(report_path):os.mkdir(report_path)
    report_abspath = os.path.join(report_path,now+"result.html")
    print("report path:%s"%report_abspath)

    fp = open(report_abspath,"wb")
    runner = HTMLTestRunnerCN_test.HTMLTestRunner(stream=fp,title="自动化接口测试报告,测试结果如下:",
                                           description="用例执行情况")
    # 调用add_case函数
    runner.run(all_case)
    fp.close()


def get_report_file(report_path):
    """第三步:获取最新的测试报告"""
    lists = os.listdir(report_path)
    lists.sort(key=lambda fn:os.path.getmtime(os.path.join(report_path,fn)))
    print("最新测试生成的报告:"+lists[-1])
    # 找到生成最新的报告文件
    report_file = os.path.join(report_path,lists[-1])
    return report_file

def send_mail(sender,psw,receiver,smtpserver,report_file,port):
    """第四步:发送最新的测试报告内容"""
    with open(report_file,"rb") as f:
        mail_body = f.read()

    # 定义邮件内容
    msg = MIMEMultipart()
    body = MIMEText(mail_body,_subtype="html",_charset="utf-8")
    msg["Subject"] = "自动化测试报告"
    msg["from"] = sender
    msg["to"] = receiver
    msg.attach(body)

    # 添加附件
    att = MIMEText(open(report_file,"rb").read(),"base64","utf-8")
    att["Content-Type"] = "application/octet-stream"
    att["Content-Disposition"] = "attachment;filename = 'report.html'"
    msg.attach(att)
    try:
        smtp = smtplib.SMTP_SSL(smtpserver,port)
    except:
        smtp = smtplib.SMTP()
        smtp.connect(smtpserver,port)

    # 用户名密码
    smtp.login(sender,psw)
    smtp.sendmail(sender,receiver,msg.as_string())
    smtp.quit()
    print("test report email has send out")

if __name__ == '__main__':

    test_data.init_data() # 初始化接口测试数据

    all_case = add_case() # 加载用例
    run_case(all_case)  # 执行用例

    report_path = os.path.join(cur_path,"report")
    report_file = get_report_file(report_path)

    # 邮箱配置,邮箱信息获取
    sender = readEmailConfig.sender
    psw = readEmailConfig.psw
    smtp_server = readEmailConfig.smtp_server
    port = readEmailConfig.port
    receiver = readEmailConfig.receiver
    send_mail(sender,psw,receiver,smtp_server,report_file,port) # 调用发送邮件方法

 

执行脚本

1.执行run_main.py 脚本会在report目录生成一个html文件

2.用例全部执行通过

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python+Requests-2-接口自动化脚本实现(虫师-Django接口测试实例) 的相关文章

  • Spring学习笔记2:注解开发、AOP思想、整合Mybatis、事务

    文章目录 7 使用注解开发 7 1 属性如何注入 1 Component 2 Value 7 2 衍生的注解 7 3 自动装配 7 4 作用域 1 Scope singleton 7 5 小结 9 使用java的方式配置Spring 9 1
  • flink连接kafka报:org.apache.kafka.common.errors.TimeoutException: Timeout expired while fetching topic

    报错信息 Caused by org apache flink runtime JobException Recovery is suppressed by NoRestartBackoffTimeStrategy at org apach
  • 跑通SOLOV1-V2实例分割代码,并训练自己的数据集。

    系统平台 Ubuntu18 04 硬件平台 RTX2080 super cuda和cudnn版本 cuda10 0 cudnn 7 5 6 pytorch版本 pytorch1 2 0 环境安装 创建solo虚拟环境 conda creat
  • 图(一)之邻接表Adjacency List

    开始攻克图的算法 先从最简单的存储开始实现 本文关于邻接表的实现 邻接表是图的存储中最简单也是最基本的存储结构 基于链表的思想实现的 在邻接表中 对于中的每个顶点建立一个单链表 第i个单链表中的节点表示依附于顶点的vi的边 每个节点由3个域
  • Android进阶之光:Dagger2原理简要分析

    Dagger2注入框架原理简要分析 使用Dagger2需要的依赖 implementation com google dagger dagger android 2 46 implementation com google dagger d
  • 实训九 网络服务的基本配置

    实训九 网络服务的基本配置 2017 年 4 月 16 日 今日公布 实训目标 完成本次实训 将能够 配置网卡 配置xinetd超级服务器 实训准备 两台计算机 其中一台安装RHEL6系统 该系统出来root账号外 至少还有一个普通账号 另
  • 【Linux系统编程】静态库和共享库

    个人博客 https blog csdn net Newin2020 spm 1011 2415 3001 5343 专栏地址 Linux系统编程 专栏定位 整理一下 C 相关的知识点 供大家学习参考 如果有收获的话 欢迎点赞 收藏 您的支
  • YOLOv5小目标检测(方法与评价)

    问题 当我们在对小目标数据集进行检测时 发现无论如何都有一些漏检的 其中我们也添加一些模块 以及其他的一些改进方法 如注意力 激活函数等等 结果始终不会令人满意 map也没有丝毫的提升 目的 增加对小目标的检测能力 不能产生漏检 自述 许多
  • ARM芯片学习(S5PV210开发)——GPIO控制LED

    1 GPIO介绍 GPIO general purpose input output 通用输入输出 GPIO就是芯片的引脚 是比较特殊的引脚 可以通过代码来操作 控制引脚的高低电平以及工作模式 与GPIO相对的就是固定功能的引脚 我们不能通
  • FPGA笔记8——串口通信(回环实验)

    目录 串口通信原理 串行通信基础知识 处理器与外部设备通信的两种方式 串行通信的通信方式 串行通信的传输方向 常见的串行通信接口 异步串口通信UART基础知识 数据格式 传输速率 接口标准 RS232接口 串口通信实验RS 232 实验任务
  • LeetCode-斐波那契数列

    class Solution public int Fibonacci int n if n 0 return 0 if n 1 return 1 return Fibonacci n 1 Fibonacci n 2 int a 0 b 1
  • 1 RocketMQ简介

    简介 RocketMQ是由阿里捐赠给Apache的一款低延迟 高并发 高可用 高可靠的分布式消息中间件 经历了淘宝双十一的洗礼 RocketMQ既可为分布式应用系统提供异步解耦和削峰填谷的能力 同时也具备互联网应用所需的海量消息堆积 高吞吐
  • 深入解决Linux内存管理之page fault处理

    说明 Kernel版本 4 14 ARM64处理器 Contex A53 双核 使用工具 Source Insight 3 5 Visio 1 概述 内核实现只是在进程的地址空间建立好了vma区域 并没有实际的虚拟地址到物理地址的映射操作
  • 《学会提问》-批判性思维

    这本书名为学会提问 但实际内容是讲解如何训练批判性思维能力 如何通过提问 来质疑别人的观点 选择正确的论证 来形成自己的理性决策 批判性思维的最终结果就是要求一个人虚怀若谷地接纳各种观点 理性评判这些观点 然后在理性判断的基础上决定采取哪些
  • 如何使用python调用电脑麦克录音

    import wave import pyaudio 定义数据流块 CHUNK 1024 FORMAT pyaudio paInt16 CHANNELS 2 RATE 44100 录音时间 RECORD SECONDS 5 要写入的文件名
  • 华为OD机试 C++ 回文字符串

    题目 什么是 回文串 就是一个字符串正着读和反着读都一样 而且要注意大小写的区别 例如 leVel 是一个回文串 因为正着反着都一样 art 就不是 反过来就变成 tra 了 Level 也不是 因为大小写不同 现在 你要做的就是用给定的一
  • NOIP中的数学--第6课 计数原理 (上)

    加法原理与乘法原理 1 加法原理 完成一个工程可以有n类办法 ai代表第i类方法的数目 那么完成这件事共有 S a 1 a 2 a n 种不同的方法 2 乘法原理 完成一个工程需要分n个步骤 ai 代表第i个步骤的不同方法数目 那么完成这件
  • python3 通过 pybind11 使用Eigen加速

    python是很容易上手的编程语言 但是有些时候使用python编写的程序并不能保证其运行速度 例如 while 和 for 这个时候我们就需要借助c 等为我们的代码提速 下面是我使用pybind11调用c 的Eigen库的简单介绍 第一步

随机推荐

  • 实现页面失去焦点十秒后强制执行js

    页面失去焦点后开始倒计时 时间到了执行指定js 适用于 检测页面无操作退出登录 在线答题防止切换页面搜索答案 浏览页面多久后获取奖励等场景
  • 概率论与数理统计--排列组合(一)

    排列 从n个不同元素中 任取m m n m与n均为自然数 下同 个元素按照一定的顺序排成一列 叫做从n个不同元素中取出m个元素的一个排列 从n个不同元素中取出m m n 个元素的所有排列的个数 叫做从n个不同元素中取出m个元素的排列数 用符
  • 118.杨辉三角

    一 题目 118 杨辉三角 力扣 LeetCode 二 代码 class Solution public vector
  • 开关电源环路稳定性分析(2)-从开环到闭环

    大家好 这里是大话硬件 在上一节中 基于欧姆定律 基尔霍夫定律 伏秒平衡这些已知的知识点 可以推导出Buck变换器的输入输出关系 今天这一节 我们还是从全局的概念来解析开关电源 1 运放和开关电源 如果一上来就分析开关电源的环路稳定性 我估
  • Spring Boot中集成Redis

    14 1 简介 redis是一款高性能的NOSQL系列的非关系型数据库 14 1 1 非关系型数据库的优势 1 性能NOSQL是基于键值对的 可以想象成表中的主键和值的对应关系 而且不需要经过SQL层的解析 所以性能非常高 2 可扩展性同样
  • 华为三层交换机STP配置

    学习目的 掌握启用和关闭STP的方法 了解不同的STP模式的差异 掌握修改网桥优先级影响根网桥选举的方法 掌握修改端口优先级影响根端口与指定端口选举的方法 掌握配置边缘的方法 拓扑图 场景 你是公司的网络管理员 公司的网络使用了两层网络结构
  • Redis基础--认识redis和对比同类型产品

    一 redis定义与应用 Nosql定义 NoSQL是不同于传统的关系数据库的数据库管理系统的统称 其两者最重要的区别是NoSQL不使用SQL作为查询语言 MySQL定义 MySQL是一种关系型数据库 关系型数据库的一个常见用法是存储长期的
  • 如何大批量压缩图片

    一 ImageMagick ImageMagick 是一个功能强大的命令行图像处理工具 可以用于批量处理图片 它支持各种图像格式和操作 包括压缩和优化 二 使用 ImageMagick 进行大批量压缩指定路径的图片 你可以通过以下步骤实现
  • JavaScript中的内存回收机制

    JS的内存回收 在js中 垃圾回收器每隔一段时间就会找出那些不再使用的数据 并释放其所占用的内存空间 以全局变量和局部变量来说 函数中的局部变量在函数执行结束后这些变量已经不再被需要 所以垃圾回收器会识别并释放它们 而对于全局变量 垃圾回收
  • 宝塔中 nodejs项目 nginx 网站基础/代理设置

    上面是一些基础配置就不写了 吧请求全部代理到 nodejs 项目 location 如果使用pm2等启动node项目 需要加header头 防止读取不到客户端IP proxy set header Host proxy host proxy
  • 生态伙伴

    提到时间管理 想必大多数人的第一反应就是 番茄工作法 番茄工作法是意大利人弗朗西斯科 西里洛于1992年创立的 他和我们大多数人一样 是一个重度拖延症患者 在他大学生活的前几年 曾一度苦于学习效率低下 于是他做了个简单的实验 他找来形状像番
  • JMeter下载及使用

    前言 我是个前端 只是一次偶然的机会被安排用了一次JMeter 做了下步骤记录 所以内容比较基础 想深入研究的兄弟可以再多找找哈 一 下载 官网地址 Apache JMeter Download Apache JMeter 下载zip包 应
  • 计算机网络的软件系统包括哪几部分,系统软件由哪几部分组成?

    系统软件用于实现计算机系统的管理 调度 监视和服务等功能 其目的是方便用户 提高计算机使用效率 扩充系统的功能 通常将系统软件分为以下六类 1 操作系统操作系统是控制和管理计算机各种资源 自动调度用户作业程序 处理各种中断的软件 操作系统的
  • 邮件发送接收原理

    概述 电子邮件是因特网上使用得非常多的一种应用 它可以非常方便的使相隔很远的人进行通信 它主要的特点就是操作简单 快捷 当你发送一封邮件的时候 它首先会发送到收件人的邮件服务器上 并放入收件人的信箱中 如果你在某一个邮件服务器提供商那里申请
  • 建站系列(二)--- 域名、IP地址、URL、端口详解

    目录 相关系列文章 前言 一 IP地址 二 域名与IP地址 三 域名与URL 四 IP地址与端口号 相关系列文章 建站系列 一 网站基本常识 建站系列 二 域名 IP地址 URL 端口详解 建站系列 三 网络协议 建站系列 四 Web服务器
  • Altium Designer 9 学习笔记(二)制作完整的原理图并在此基础上导出PCB版图

    首先 先说下本次练习对象 简单的光敏小夜灯 1 制作原理图 按制图流程 1 1 新建工程及原理图 F N J B 一套连招创建PCB工程 然后右键为新建的工程添加原理图文件 完成后如下图所示 1 2 加载元器件并生成序号 1 2 1 加入电
  • excel转换pdf方法 (aspose.cells亲测有效)

    AsposeUtils java package com lmp test utils import com aspose cells License import com aspose cells PdfSaveOptions impor
  • 北航学长:DCIC 2021的算法方案讲解

    作者 阿水 北京航空航天大学 Datawhale成员 DCIC 作为每年具有重要影响力的政府赛事 除了高认可 高奖金 最重要的是开放了政府和企业的真实数据 具有研究和落地价值 但对于刚参加赛事的同学 还是有难度的 希望通过分享让更初学者也能
  • 网管员牢记10种较为常见服务器管理错误

    网络管理阶层的工作就是保证网络的正常工作 从而使得职工们的工作不被打断 可问题在于事物并非总是按照理想状况发展 事实上经常会出现平地起风波的状况 其间有许多原因 这里我们只讨论10种较为常见的网管错误 1 UPS 不间断电源 的使用问题 某
  • Python+Requests-2-接口自动化脚本实现(虫师-Django接口测试实例)

    编写脚本前分析项目架构 需求 python脚本实现 添加发布会信息 的接口测试 以邮件形式发送测试报告 1 新建一个case目录 存放测试用例 2 新建一个config目录 存放配置信息和读取配置信息 3 新建一个db fixture目录