点击文末小卡片免费获取软件测试全套资料资料在手涨薪更快框架产生目的公司走的是敏捷开发模式编写这种框架是为了能够满足当前这种发展模式用于前后端联调之前后端开发完接口前端还没有将业务处理完毕的时候以及日后回归阶段方便为自己腾出学(mo)习(yu)时间。鄙人一介小测试一手承接产品一手面对开发4个后端3个web前端外加不知道几个的乙方项目经手了5批人鄙人是第5批的测试规范没有前人积累没有天崩开局/(ㄒoㄒ)/~~。老规矩上图这个不直观下面我来展示这个抽象的图片美术功底差见谅怎么是不是有一种UI自动化里面的POM思想没错这正是这个思路在API自动化里里面的一个体现。毕竟服务间的调用是复杂的将各个接口封装起来对应的py文件里面创一个main方法用于单个接口入参以及返回值之间的验证至于接口之间的串联那就放到下面regression_test里面每一个case相当于一个过程如上传习题、选题、组卷分发、上传试卷、批阅等流程辅以逻辑处理大部分的流程还是可以自动化实现的ps对于前后端联调加改bug用了两个月时间才圆满搞定的过程我没敢尝试将这个给自动化实现了还是留待后人吧。getpathInfo.py:获取autoapi文件夹所在的目录便于项目换家有没有其实无所谓的import os def get_path(): path os.path.split(os.path.realpath(__file__))[0] return path if __name__ __main__: print(测试路径是否OK,路径为, get_path())readConfig.pyimport os import configparser import getpathInfo path getpathInfo.get_path() config_path os.path.join(path, config) config configparser.ConfigParser() # 调用外部的读取配置文件的方法 config.read(config_path, encodingutf-8) class ReadConfig(): def get_http(self, name): value config.get(HTTP, name) return value def get_email(self, name): value config.get(EMAIL, name) return value def get_account(self, name): value config.get(ACCOUNT, name) return value environment 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.py123456789101112131415161718192021222324252627282930313233343536373839404142434445464748importloggingimporttimefromgetpathInfoimportget_pathclassLog(object):def__init__(self, loggerNone):指定保存日志的文件路径日志级别以及调用文件将日志存入到指定的文件中# 创建一个loggerself.loggerlogging.getLogger(logger)self.logger.setLevel(logging.DEBUG)# 创建一个handler用于写入日志文件self.log_timetime.strftime(%Y-%m_%d_)self.log_pathget_path()\\log\\self.log_nameself.log_pathself.log_timetest.logfhlogging.FileHandler(self.log_name,a, encodingutf-8)# 追加模式防止中文乱码fh.setLevel(logging.INFO)# 再创建一个handler用于输出到控制台chlogging.StreamHandler()ch.setLevel(logging.INFO)# 定义一个handler的输出样式formatterlogging.Formatter([%(asctime)s] %(filename)s-%(funcName)s line:%(lineno)d [%(levelname)s]%(message)s)fh.setFormatter(formatter)ch.setFormatter(formatter)# 给logger添加handlerself.logger.addHandler(fh)self.logger.addHandler(ch)# 添加下面一句在记录日志之后移除句柄fh.close()ch.close()defgetLog(self):returnself.loggerlogLog().getLog()if__name____main__:log.info(日志)# 抄过来的代码一定要进行测试configHttp.py这里是默认加上token的但是并不是所有接口都是需要token解决思路再加个configHttpNormal.py。对于同一个系统中需要多个用户参与的过程这时候就需要配置文件里面再多一位用户的账号密码了再加一个login()方法并赋值下面的对应的基础请求封装里面要再多一个参数is_other_one,默认为false一但给true下面headers就要换参数中的值import json import requests from 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;charsetUTF-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(urlenvironmentpath,datajson.dumps(data,ensure_asciiFalse,separators(,,:)).encode(utf-8), headersheaders,verifyFalse) log.info(path) # path log.info(data) # 请求便于复现 log.info(response.status_code) # 请求状态码 return response def send_get(self, path, data): response requests.get(urlenvironmentpath, datadata, headersheaders,verifyFalse) log.info(path) log.info(data) log.info(response.status_code) return response def run_main(self, method, pathNone, dataNone): result None if method.lower() post: result self.send_post(path, data) elif method.lower() get: result self.send_get(path, data) else: print(method值错误!!!) return result if __name__ __main__: result1 RunMain().run_main(get, /v1/wrong-work/info?type1).json() result2 RunMain().run_main(Get, /v1/wrong-work/info?type2).json() print(result1) print(result2)case用例文件夹,敏捷模式中开发提测基本上都是单接口提测而且同一个模块下的接口分给了不同的开发为了方便定位到开发所以我将平台所有的接口都写了过来╮(╯▽╰)╭老规矩下方直接执行可以进行单接口的相关验证。相信各位也看了很多的接口自动化测试框架我上面的应该没有多少新意下面就是不同点regression_testing 顾名思义回归测试ing只有进行时没有完成时……鄙人将前端的业务逻辑通过接口层模拟了过来做了许久之后不禁产生了怀疑这都是哪位鬼才设计的没有被开发XX了吗上图是使用unittest框架进行的用例之间传参用法其实就是我上面展示的一部分其实这个文件夹下不适合使用unittest框架因为通过用例之间的巧妙设计虽然可以将业务之间的调用状态都模拟出来但是由于脏数据的存在某些bug没有在这些测试过程中表示出来。哎苦命啊前端赶紧进行插桩操作报错日志上传起来鄙人只能放大招了拾起了爬虫思路自动遍历吧穷举放代码片段,哎遍历一时爽重构火葬场(json目录深了之后是真的不想看)。之后优化思路将regression_testing里面的方法改成test_*写一个run方法加上测试报告邮件通知ps但鄙人不用啊就十个人遇到bugtapd复制上参数“老哥出bug了”是不是也发现了少了很多东西写个装饰器用于统计时间接口请求超时也要打印出来其实还有一个文件夹用来写压测脚本基于locust的FasthttpUserlog文件夹中的path以及data都是直接可以在locust中使用的省了构造数据的时间locust脚本如下部分更详细的可以看看httprunner的实现思路大神写的比我强太多了还是得学啊。最后感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你凡事要趁早特别是技术行业一定要提升技术功底。