基于Python+requests编写的自动化测试项目-实现流程化的接口串联

框架产生目的:公司走的是敏捷开发模式,编写这种框架是为了能够满足当前这种发展模式,用于前后端联调之前(后端开发完接口,前端还没有将业务处理完毕的时候)以及日后回归阶段,方便为自己腾出学(mo)习(yu)时间。

鄙人一介小测试,一手承接产品,一手面对开发(4个后端,3个web前端,外加不知道几个的乙方),项目经手了5批人,鄙人是第5批的测试,规范没有,前人积累没有,天崩开局/(ㄒoㄒ)/~~。

老规矩,上图:

这个不直观,下面我来展示这个抽象的图片(美术功底差,见谅):

怎么,是不是有一种UI自动化里面的POM思想?没错,这正是这个思路在API自动化里里面的一个体现。

毕竟服务间的调用是复杂的,将各个接口封装起来,对应的py文件里面创一个main方法,用于单个接口入参以及返回值之间的验证,至于接口之间的串联,那就放到下面(regression_test里面,每一个case相当于一个过程,如:上传习题、选题、组卷分发、上传试卷、批阅等流程),辅以逻辑处理,大部分的流程还是可以自动化实现的(ps:对于前后端联调加改bug用了两个月时间才圆满搞定的过程,我没敢尝试将这个给自动化实现了,还是留待后人吧)。

getpathInfo.py:获取autoapi文件夹所在的目录,便于项目换家,有没有其实无所谓的;

import osdef get_path():path = os.path.split(os.path.realpath(__file__))[0]return pathif __name__ == '__main__':print('测试路径是否OK,路径为:', get_path())

readConfig.py

import os
import configparser
import getpathInfopath = getpathInfo.get_path()  
config_path = os.path.join(path, 'config')  
config = configparser.ConfigParser()  # 调用外部的读取配置文件的方法
config.read(config_path, encoding='utf-8')class ReadConfig():def get_http(self, name):value = config.get('HTTP', name)return valuedef get_email(self, name):value = config.get('EMAIL', name)return valuedef get_account(self, name):value = config.get('ACCOUNT', name)return valueenvironment = ReadConfig().get_http('environment')  # 切换环境
mobile_phone = ReadConfig().get_account('mobile_phone')
password = ReadConfig().get_account('password')
parent_username = ReadConfig().get_account('parent_phone')
parent_pwd = ReadConfig().get_account('parent_pwd')

common:公共方法文件夹,最省事配置:日志封装(中文日志在这里要留意,有坑),请求封装(如果有token之类的限制的话)

logs.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

import logging

import time

from getpathInfo import get_path

class Log(object):

    def __init__(self, logger=None):

        """

        指定保存日志的文件路径,日志级别,以及调用文件

        将日志存入到指定的文件中

        """

        # 创建一个logger

        self.logger = logging.getLogger(logger)

        self.logger.setLevel(logging.DEBUG)

        # 创建一个handler,用于写入日志文件

        self.log_time = time.strftime('%Y-%m_%d_')

        self.log_path = get_path()+'\\log\\'

        self.log_name = self.log_path + self.log_time + 'test.log'

        fh = logging.FileHandler(self.log_name, 'a', encoding='utf-8')  # 追加模式,防止中文乱码

        fh.setLevel(logging.INFO)

        # 再创建一个handler,用于输出到控制台

        ch = logging.StreamHandler()

        ch.setLevel(logging.INFO)

        # 定义一个handler的输出样式

        formatter = logging.Formatter(

            '[%(asctime)s] %(filename)s->%(funcName)s line:%(lineno)d [%(levelname)s]%(message)s')

        fh.setFormatter(formatter)

        ch.setFormatter(formatter)

        # 给logger添加handler

        self.logger.addHandler(fh)

        self.logger.addHandler(ch)

        #  添加下面一句,在记录日志之后移除句柄

        fh.close()

        ch.close()

    def getLog(self):

        return self.logger

log = Log().getLog()

if __name__ == '__main__':

    log.info('日志')  # 抄过来的代码一定要进行测试

configHttp.py

这里是默认加上token的,但是并不是所有接口都是需要token,解决思路:再加个configHttpNormal.py。

对于同一个系统中需要多个用户参与的过程,这时候就需要配置文件里面再多一位用户的账号密码了,再加一个login()方法并赋值,下面的对应的基础请求封装里面要再多一个参数:is_other_one,默认为false,一但给true,下面headers就要换参数中的值;

import json
import requestsfrom common.logs import log
from readConfig import environment,mobile_phone,password
from case.api.User import login
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)  # 如果有抓包需求,需要把verify设置成False,这行代码忽略系统之后的警告
"""
这个文件主要来通过get、post等方法来进行http请求,并拿到请求响应
"""token = login(mobile_phone,password) # 登录方法
headers = {'Authorization': token,"Content-Type": 'application/json;charset=UTF-8','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'}class RunMain():def send_post(self, path, data):response = requests.post(url=environment+path,data=json.dumps(data,ensure_ascii=False,separators=(',',':')).encode('utf-8'), headers=headers,verify=False)log.info(path)  # pathlog.info(data)  # 请求,便于复现log.info(response.status_code)  # 请求状态码return responsedef send_get(self, path, data):response = requests.get(url=environment+path, data=data, headers=headers,verify=False)log.info(path)log.info(data)log.info(response.status_code)return responsedef run_main(self, method, path=None, data=None):result = Noneif method.lower() == 'post':result = self.send_post(path, data)elif method.lower() == 'get':result = self.send_get(path, data)else:print("method值错误!!!")return resultif __name__ == '__main__':result1 = RunMain().run_main('get', '/v1/wrong-work/info?type=1').json()result2 = RunMain().run_main('Get', '/v1/wrong-work/info?type=2').json()print(result1)print(result2)

case:用例文件夹,敏捷模式中开发提测基本上都是单接口提测,而且同一个模块下的接口分给了不同的开发,为了方便定位到开发,所以我将平台所有的接口都写了过来╮(╯▽╰)╭,

老规矩,下方直接执行,可以进行单接口的相关验证。

相信各位也看了很多的接口自动化测试框架,我上面的应该没有多少新意,下面就是不同点;

regression_testing 顾名思义,回归测试ing,只有进行时,没有完成时……

鄙人将前端的业务逻辑通过接口层模拟了过来,做了许久之后,不禁产生了怀疑:这都是哪位鬼才设计的?没有被开发XX了吗?

上图是使用unittest框架进行的,用例之间传参用法其实就是我上面展示的一部分;

其实这个文件夹下不适合使用unittest框架,因为通过用例之间的巧妙设计,虽然可以将业务之间的调用状态都模拟出来,但是由于脏数据的存在,某些bug没有在这些测试过程中表示出来。

哎,苦命啊,前端赶紧进行插桩操作,报错日志上传起来;鄙人只能放大招了,拾起了爬虫思路,自动遍历吧(穷举);

放代码片段,哎,遍历一时爽,重构火葬场(json目录深了之后,是真的不想看)。

之后优化思路:将regression_testing里面的方法改成test_*,写一个run方法,加上测试报告,邮件通知(ps:但鄙人不用啊,就十个人,遇到bug,tapd复制上参数,“老哥,出bug了”)

是不是也发现了,少了很多东西?写个装饰器(用于统计时间),接口请求超时也要打印出来;

 其实还有一个文件夹,用来写压测脚本(基于locust的FasthttpUser),log文件夹中的path以及data都是直接可以在locust中使用的,省了构造数据的时间;

locust脚本如下(部分),更详细的可以看看httprunner的实现思路,大神写的比我强太多了,还是得学啊。

  

Python接口自动化测试零基础入门到精通(2023最新版)

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

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

相关文章

图像异常检测研究现状综述

论文标题:图像异常检测研究现状综述 作者:吕承侃 1, 2 沈 飞 1, 2, 3 张正涛 1, 2, 3 张 峰 1, 2, 3 发表日期:2022年6月 阅读日期 :2023年11月28 研究背景: 图像异常检测是计算机视觉领域的一个热门研究课题, 其目…

leetCode 39.组合总和 + 回溯算法 + 剪枝 + 图解 + 笔记

39. 组合总和 - 力扣(LeetCode) 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合 can…

2015年五一杯数学建模A题不确定性条件下的最优路径问题解题全过程文档及程序

2015年五一杯数学建模 A题 不确定性条件下的最优路径问题 原题再现 目前,交通拥挤和事故正越来越严重的困扰着城市交通。随着我国交通运输事业的迅速发展,交通“拥塞”已经成为很多城市的“痼疾”。在复杂的交通环境下,如何寻找一条可靠、快…

HarmonyOS 数据持久化 Preferences 如何在页面中对数据进行读写

背景介绍 最近在了解并跟着官方文档尝试做一个鸿蒙app 小demo的过程中对在app中保存数据遇到些问题 特此记录下来 这里的数据持久化以 Preferences为例子展开 废话不多说 这里直接上节目(官方提供的文档示例:) 以Stage模型为例 1.明确preferences的类型 import data_prefer…

印刷企业建设数字工厂管理系统的工作内容有哪些

随着科技的不断进步,数字工厂管理系统在印刷企业中的应用越来越广泛。这种系统可以有效地整合企业内外资源,提高生产效率,降低生产成本,并为印刷企业提供更好的业务运营与管理模式。本文将从以下几个方面探讨印刷企业建设数字工厂…

如何用postman实现接口自动化测试

postman使用 开发中经常用postman来测试接口,一个简单的注册接口用postman测试: 接口正常工作只是最基本的要求,经常要评估接口性能,进行压力测试。 postman进行简单压力测试 下面是压测数据源,支持json和csv两个格…

Kibana部署

服务器 安装软件主机名IP地址系统版本配置KibanaElk10.3.145.14centos7.5.18042核4G软件版本:nginx-1.14.2、kibana-7.13.2-linux-x86_64.tar.gz 1. 安装配置Kibana (1)安装 [rootelk ~]# tar zxf kibana-7.13.2-linux-x86_64.tar.gz -C…

easyExcel 注解开发 快速以及简单上手 以及包含工具类

easyExcel 简单快速使用 1. mevan 这里版本我这里选的是 poi 4.1.2和 ali的easyexcel 的 3.3.1。 因为阿里easy是根据poi的依赖开发的有关系,两者需要对应要不然就会有很多bug和错误在运行时发生。需要版本对应,然而就是easy的代码也会有bug这个版本是比…

运动鞋品牌识别

一、前期工作 1. 设置GPU from tensorflow import keras from tensorflow.keras import layers,models import os, PIL, pathlib import matplotlib.pyplot as plt import tensorflow as tfgpus tf.config.list_physical_devices("GPU")if gpus:gpu0 …

Leetcode—18.四数之和【中等】

2023每日刷题&#xff08;四十一&#xff09; Leetcode—18.四数之和 实现代码 class Solution { public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ans;sort(nums.begin(), nums.end());int n …

chatgpt prompt提示词

ChatGPT 最近十分火爆&#xff0c;今天我也来让 ChatGPT 帮我阅读一下 Vue3 的源代码。 都知道 Vue3 组件有一个 setup函数。那么它内部做了什么呢&#xff0c;今天跟随 ChatGPT 来一探究竟。 实战 1.setup setup 函数在什么位置呢&#xff0c;我们不知道他的实现函数名称&…

12 网关实战:Spring Cloud Gateway基础理论

为什么需要网关? 传统的单体架构中只有一个服务开放给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,那么作为客户端如何去调用这些微服务呢?如果没有网关的存在,只能在本地记录每个微服务的调用地址。 无网关的微服务架构往往存在以下问题: 客户端多次请求…

人机交互3——多主题多轮对话

1.主动切换 2.被动切换 3.多轮状态记忆

3.2 Windows驱动开发:内核CR3切换读写内存

CR3是一种控制寄存器&#xff0c;它是CPU中的一个专用寄存器&#xff0c;用于存储当前进程的页目录表的物理地址。在x86体系结构中&#xff0c;虚拟地址的翻译过程需要借助页表来完成。页表是由页目录表和页表组成的&#xff0c;页目录表存储了页表的物理地址&#xff0c;而页表…

使用Sui天气预言机获取全球实时天气数据

新的Sui天气预言机为全球1000多个城市的建设者提供天气数据&#xff0c;并作为一个独特的随机数生成器&#xff0c;适用于需要可信赖的随机结果的游戏和投注应用。它由基于Sui的智能合约和一个从OpenWeather API获取天气数据的后端服务组成&#xff0c;任何人都可以将天气数据集…

SpringCloudAlibaba之Nacos——详细讲解

目录 一、SpringCloudAlibaba简介 1. spring cloud alibaba 特点 2.springcloud 组件 二、环境搭建 1.构建项目并引入依赖 三、Nacos 1.什么是Nacos 2.安装Nacos 3.启动安装服务 4.访问nacos的web服务管理界面 四、开发服务注册到nacos 1.创建项目并引入依赖 2.配置注册地…

【Linux】了解进程的基础知识

进程 1. 进程的概念1.1 进程的理解1.2 Linux下的进程1.3 查看进程属性1.4 getpid和getppid 2. 创建进程3. 进程状态4. 进程优先级5. 进程切换6. 环境变量7. 本地变量与内建命令 1. 进程的概念 一个已经加载到内存中的程序&#xff0c;叫做进程&#xff08;也叫任务&#xff09…

Python+Selenium WebUI自动化框架 -- 基础操作封装

前言&#xff1a; 封装Selenium基本操作&#xff0c;让所有页面操作一键调用&#xff0c;让UI自动化框架脱离高成本、低效率时代&#xff0c;将用例的重用性贯彻到极致&#xff0c;让烦人的PO模型变得无所谓&#xff0c;让一个测试小白都能编写并实现自动化。 知识储备前提&a…

中小型公司如何搭建运维平台,rancher、kubersphere、rainbond

很多开发人员应该是了解过运维发布相关的平台或实际操作过应用发布&#xff0c;但又通常不是十分熟悉。在一个初创公司&#xff0c;或者没有成熟的运维发布平台的公司&#xff0c;如果让你来搭建一套发布平台&#xff0c;你应该如何去抉择呢&#xff1f; 这里我简单介绍几种。…

【Linux】:信号在内核里的处理

信号的发送和保存 一.内核中的信号处理二.信号集操作函数1.一些信号函数2.sigprocmask3.sigpending4.写代码 三.信号在什么时候处理的四.再谈地址空间 一.内核中的信号处理 1.实际执行信号的处理动作称为信号递达(Delivery )2.信号从产生到递达之间的状态,称为信号未决(Pending…