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

本文主要是介绍基于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最新版)

这篇关于基于Python+requests编写的自动化测试项目-实现流程化的接口串联的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/431348

相关文章

C#借助Spire.XLS for .NET实现在Excel中添加文档属性

《C#借助Spire.XLSfor.NET实现在Excel中添加文档属性》在日常的数据处理和项目管理中,Excel文档扮演着举足轻重的角色,本文将深入探讨如何在C#中借助强大的第三方库Spire.... 目录为什么需要程序化添加Excel文档属性使用Spire.XLS for .NET库实现文档属性管理Sp

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Python实现快速扫描目标主机的开放端口和服务

《Python实现快速扫描目标主机的开放端口和服务》这篇文章主要为大家详细介绍了如何使用Python编写一个功能强大的端口扫描器脚本,实现快速扫描目标主机的开放端口和服务,感兴趣的小伙伴可以了解下... 目录功能介绍场景应用1. 网络安全审计2. 系统管理维护3. 网络故障排查4. 合规性检查报错处理1.

Python轻松实现Word到Markdown的转换

《Python轻松实现Word到Markdown的转换》在文档管理、内容发布等场景中,将Word转换为Markdown格式是常见需求,本文将介绍如何使用FreeSpire.DocforPython实现... 目录一、工具简介二、核心转换实现1. 基础单文件转换2. 批量转换Word文件三、工具特性分析优点局

Python中4大日志记录库比较的终极PK

《Python中4大日志记录库比较的终极PK》日志记录框架是一种工具,可帮助您标准化应用程序中的日志记录过程,:本文主要介绍Python中4大日志记录库比较的相关资料,文中通过代码介绍的非常详细,... 目录一、logging库1、优点2、缺点二、LogAid库三、Loguru库四、Structlogphp

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

Java使用Spire.Doc for Java实现Word自动化插入图片

《Java使用Spire.DocforJava实现Word自动化插入图片》在日常工作中,Word文档是不可或缺的工具,而图片作为信息传达的重要载体,其在文档中的插入与布局显得尤为关键,下面我们就来... 目录1. Spire.Doc for Java库介绍与安装2. 使用特定的环绕方式插入图片3. 在指定位

Java使用Spire.Barcode for Java实现条形码生成与识别

《Java使用Spire.BarcodeforJava实现条形码生成与识别》在现代商业和技术领域,条形码无处不在,本教程将引导您深入了解如何在您的Java项目中利用Spire.Barcodefor... 目录1. Spire.Barcode for Java 简介与环境配置2. 使用 Spire.Barco