当前位置:文档之家› 接口自动化测试框架实例详解教程python+requests

接口自动化测试框架实例详解教程python+requests

接口自动化测试框架实例详解教程python+requests前段时间由于公司测试方向的转型,由原来的web页面功能测试转变成接口测试,之前大多都是手工进行,利用postman和jmeter进行的接口测试,后来,组内有人讲原先web自动化的测试框架移驾成接口的自动化框架,使用的是java语言,但对于一个学java,却在学python的我来说,觉得python比起java更简单些,所以,我决定自己写python的接口自动化测试框架,由于本人也是刚学习python,这套自动化框架目前已经基本完成了,于是进行一些总结,便于以后回顾温习,有许多不完善的地方,也遇到了许多的问题,希望大神们多多指教。

下面我就进行今天的主要内容吧。

1、首先,我们先来理一下思路。

正常的接口测试流程是什么?脑海里的反应是不是这样的:确定测试接口的工具—> 配置需要的接口参数—> 进行测试—> 检查测试结果(有的需要数据库辅助)—> 生成测试报告(html报告)那么,我们就根据这样的过程来一步步搭建我们的框架。

在这个过程中,我们需要做到业务和数据的分离,这样才能灵活,达到我们写框架的目的。

只要好好做,一定可以成功。

这也是我当初对自己说的。

接下来,我们来进行结构的划分。

我的结构是这样的,大家可以参考下:common:存放一些共通的方法result:执行过程中生成的文件夹,里面存放每次测试的结果testCase:用于存放具体的测试casetestFile:存放测试过程中用到的文件,包括上传的文件,测试用例以及数据库的sql 语句caselist:txt文件,配置每次执行的case名称config:配置一些常量,例如数据库的相关信息,接口的相关信息等readConfig:用于读取config配置文件中的内容runAll:用于执行case既然整体结构有了划分,接下来就该一步步的填充整个框架了,首先,我们先来看看config.ini和readConfig.py两个文件,从他们入手,个人觉得比较容易走下去哒。

我们来看下文件的内容是什么样子的:[DATABASE]host = 50.23.190.57username = xxxxxxpassword = ******port = 3306database = databasename[HTTP]# 接口的urlbaseurl = http://xx.xxxx.xxport = 8080timeout = 1.0[EMAIL]mail_host = mail_user = xxx@mail_pass = *********mail_port = 25sender = xxx@receiver = xxxx@/xxxx@subject = pythoncontent = "All interface test has been complited\nplease read the report file about the detile of result in the attachment."testuser = Someoneon_off = 1相信大家都知道这样的配置文件,没错,所有一成不变的东西,我们都可以放到这里来。

哈哈,怎么样,不错吧。

现在,我们已经做好了固定的“仓库”。

来保存我们平时不动的东西,那么,我们要怎么把它拿出来为我所用呢?这时候,readConfig.py文件出世了,它成功的帮我们解决fd = open(configPath)data = fd.read()# remove BOMif data[:3] == codecs.BOM_UTF8:data = data[3:]file = codecs.open(configPath, "w")file.write(data)file.close()fd.close()self.cf = configparser.ConfigParser()self.cf.read(configPath)def get_email(self, name):value = self.cf.get("EMAIL", name)return valuedef get_http(self, name):value = self.cf.get("HTTP", name)return valuedef get_db(self, name):value = self.cf.get("DATABASE", name)return value怎么样,是不是看着很简单啊,我们定义的方法,根据名称取对应的值,是不是so easy?!当然了,这里我们只用到了get方法,还有其他的例如set方法,有兴趣的同学可以自己去探索下,这里我们就不在累述了。

话不多说,我们先来看下common到底有哪些东西。

既然配置文件和读取配置文件我们都已经完成了,也看到了common里的内容,接下来就可以写common里的共通方法了,从哪个下手呢?今天,我们就来翻“Log.py”的牌吧,因为它是比较独立的,我们单独跟他打交道,也为了以后它能为我们服务打下良好基础。

这里呢,我想跟大家多说两句,对于这个log文件呢,我给它单独启用了一个线程,这样在整个运行过程中,我们在写log的时候也会比较方便,看名字大家也知道了,这里就是我们对输出的日志的所有操作了,主要是对输出格式的规定,输出等级的定义以及其他一些输出的定义等等。

总之,你想对log做的任何事情,都可以放到这里来。

我们来看下代码,没有比这个更直接有效的了。

class Log:def __init__(self):global logPath, resultPath, proDirproDir = readConfig.proDirresultPath = os.path.join(proDir, "result")# create result file if it doesn't existif not os.path.exists(resultPath):os.mkdir(resultPath)# defined test result file name by localtimelogPath = os.path.join(resultPath, str(datetime.now().strftime("%Y%m%d%H%M%S")))# create test result file if it doesn't existif not os.path.exists(logPath):os.mkdir(logPath)# defined loggerself.logger = logging.getLogger()# defined log levelself.logger.setLevel()# defined handlerhandler = logging.FileHandler(os.path.join(logPath, "output.log"))# defined formatterformatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # defined formatterhandler.setFormatter(formatter)# add handlerself.logger.addHandler(handler),现在,我们创建了上面的Log类,在__init__初始化方法中,我们进行了log的相关初始化操作。

具体的操作内容,注释已经写得很清楚了(英文有点儿差,大家看得懂就行,嘿嘿……),这样,log的基本格式已经定义完成了,至于其他的方法,就靠大家自己发挥了,毕竟每个人的需求也不同,我们就只写普遍的共用方法啦。

接下来,就是把它放进一个线程内了,请看下面的代码:这也是我为什么选择它的原因,虽然小编我也是刚刚学习,还有很多不懂的地方。

好了,至此log的内容也结束了,是不是感觉自己棒棒哒~其实,无论什么时候,都不要感到害怕,要相信“世上无难事只怕有心人”。

下面,我们继续搭建,这次要做的,是configHttp.py的内容。

没错,我们开始配置接口文件啦!(终于写到接口了,是不是很开心啊~)下面是接口文件中主要部分的内容,让我们一起来看看吧。

import requestsimport readConfig as readConfigfrom common.Log import MyLog as LoglocalReadConfig = readConfig.ReadConfig()class ConfigHttp:def __init__(self):global host, port, timeouthost = localReadConfig.get_http("baseurl")port = localReadConfig.get_http("port")timeout = localReadConfig.get_http("timeout")self.log = Log.get_log()self.logger = self.log.get_logger()self.headers = {}self.params = {}self.data = {}self.url = Noneself.files = {}def set_url(self, url):self.url = host + urldef set_headers(self, header):self.headers = headerdef set_params(self, param):self.params = paramdef set_data(self, data):self.data = datadef set_files(self, file):self.files = file# defined http get methoddef get(self):try:response = requests.get(self.url, params=self.params, headers=self.headers,timeout=float(timeout))# response.raise_for_status()return responseexcept TimeoutError:self.logger.error("Time out!")return None# defined http post methoddef post(self):try:response = requests.post(self.url, headers=self.headers, data=self.data, files=self.files, timeout=float(timeout))# response.raise_for_status()return responseexcept TimeoutError:self.logger.error("Time out!")return None这里我们就挑重点来说吧。

相关主题