python接⼝⾃动化框架
基于 python 的接⼝测试框架
· · 于 5 ⽉前发布 · 最后由于 4 ⽉前回复 · 3553 次阅读
项⽬背景
公司内部的软件采⽤B/S架构,管理实验室数据,实现数据的存储和分析统计。⼤部分是数据的增删改查,由于还在开发阶段,所以UI界⾯的变化⾮常快,之前尝试过⽤python+selenium进⾏UI⾃动化测试,后来发现今天刚写好的脚本第⼆天前端就改了页⾯,⼜得重新去定位元素什么的,消耗⼤量的精⼒与时间维护⾃动化脚本。针对此种情况,对接⼝测试较为有效。
⼯具
由于开发那⾥不能提供后台代码给我,只能通过抓包分析。使⽤fiddler抓包,发现前端与后台都是采⽤POST⽅法交互,前端POST数据,后台返回数据。这样也⽐较简单粗暴,直接针对每个接⼝POST测试数据,然后观察返回值就好了。
使⽤excel编写测试⽤例和数据,requests发送HTTP请求。
功能模块
通过xlrd库读取excel中的测试⽤例和数据
requests负责发送数据并接收后台返回的数据
针对测试结果,需要保存测试⽇志并⽣成测试报告,采⽤python⾃带的logging记录⽇志,测试报告采⽤html格式。
同时测试完成后,需要将测试报告发送给相关的开发⼈员,需要有⾃动发送邮件的功能
⽬录结构
代码实现
#通过⾃带的ConfigParser模块,读取邮件发送的配置⽂件,作为字典返回
import ConfigParser
def get_conf():
conf_file = ConfigParser.ConfigParser()
ad(os.path.wd(),'conf.ini'))
conf = {}
conf['sender'] = ("email","sender")
conf['receiver'] = ("email","receiver")
conf['smtpserver'] = ("email","smtpserver")
conf['username'] = ("email","username")
selenium获取cookieconf['password'] = ("email","password")
return conf
配置⽂件格式
这个logging不熟悉的可以google⼀下,还是挺有⽤的,需要⾃⼰配置⼀下。需要⼿动新建⼀个空⽩的.log⽂件。
#此处使⽤python⾃带的logging模块,⽤来作为测试⽇志,记录测试中系统产⽣的信息。
import logging,os
log_file = os.path.wd(),'log/sas.log')
log_format = '[%(asctime)s] [%(levelname)s] %(message)s' #配置log格式
logging.basicConfig(format=log_format, filename=log_file, filemode='w', level=logging.DEBUG)
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
formatter = logging.Formatter(log_format)
console.setFormatter(formatter)
excel⽂件如下图
python读取excel跟读取⼀个⼆维数组差不多,下标也是从0开始
#读取testcase excel⽂件,获取测试数据,调⽤interfaceTest⽅法,将结果保存⾄errorCase列表中。
import xlrd,hashlib,json
def runTest(testCaseFile):
testCaseFile = os.path.wd(),testCaseFile)
if not ists(testCaseFile):
<('测试⽤例⽂件不存在!')
testCase = xlrd.open_workbook(testCaseFile)
table = testCase.sheet_by_index(0)
errorCase = [] #⽤于保存接⼝返回的内容和HTTP状态码
s = None
for i in range(ws):
ll(i, 9).place('\n','').replace('\r','') != 'Yes':
continue
num = str(ll(i, 0).value)).replace('\n','').replace('\r','')
api_purpose = ll(i, 1).place('\n','').replace('\r','')
api_host = ll(i, 2).place('\n','').replace('\r','')
request_method = ll(i, 4).place('\n','').replace('\r','')
request_data_type = ll(i, 5).place('\n','').replace('\r','')
request_data = ll(i, 6).place('\n','').replace('\r','')
encryption = ll(i, 7).place('\n','').replace('\r','')
check_point = ll(i, 8).value
if encryption == 'MD5': #如果数据采⽤md5加密,便先将数据加密
request_data = json.loads(request_data)
request_data['pwd'] = md5Encode(request_data['pwd'])
status, resp, s = interfaceTest(num, api_purpose, api_host, request_url, request_data, check_point, request_methon, request_data_type, s)
if status != 200 or check_point not in resp: #如果状态码不为200或者返回值中没有检查点的内容,那么证明接⼝产⽣错误,保存错误信息。
errorCase.append((num + ' ' + api_purpose, str(status), ''+api_host+request_url, resp))
return errorCase
下⾯的就是接⼝部分
由于所有的操作必须在系统登录之后进⾏,⼀开始没有注意到cookie这⼀点,每读取⼀个测试⽤例,都会新建⼀个session,导致⽆法维护上⼀次请求的cookie。然后将cookie添加⼊请求头中,但是第⼆个⽤例仍然⽆法执⾏成功。后来⽤fiddler抓包分析了⼀下,发现cookie的值竟然是每⼀次操作后都会变化的
所以只能通过session⾃动维护cookie。
在interfaceTest函数中,返回三个值,分别是HTTP CODE,HTTP返回值与session。再将上⼀次请求的session作为⼊参传⼊interfaceTest函数中,在函数内部判断session是否存在,如果不为None,那么直接利⽤传⼊的session执⾏下⼀个⽤例,如果为None,那么新建⼀个session。
#接受runTest的传参,利⽤requests构造HTTP请求
import requests
def interfaceTest(num, api_purpose, api_host, request_method,
request_data_type, request_data, check_point, s=None)
headers = {'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With' : 'XMLHttpRequest',
'Connection' : 'keep-alive',
'Referer' : '' + api_host,
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36'
}
if s == None:
s = requests.session()
if request_method == 'POST':
if request_url != '/login' :
r = s.post(url=''+api_host+request_url, data = json.loads(request_data), headers = headers) #由于此处数据没有经过加密,所以需要把Json格式字符串解码转换成**Python对象**
elif request_url == '/login' :
s = requests.session()
r = s.post(url=''+api_host+request_url, data = request_data, headers = headers) #由于登录
密码不能明⽂传输,采⽤MD5加密,在之前的代码中已经进⾏过json.loads()转换,所以此处不需要解码
else:
<(num + ' ' + api_purpose + ' HTTP请求⽅法错误,请确认[Request Method]字段是否正确')
s = None
return 400, resp, s
status = r.status_code
resp = r.text
print resp
if status == 200 :
if re.search(check_point, )):
logging.info(num + ' ' + api_purpose + ' 成功,' + str(status) + ', ' + ))
return status, resp, s
else:
<(num + ' ' + api_purpose + ' 失败,[' + str(status) + '], ' + ))
return 200, resp , None
else:
<(num + ' ' + api_purpose + ' 失败,[' + str(status) + '],' + ))
return status, resp.decode('utf-8'), None
import hashlib
def md5Encode(data):
hashobj = hashlib.md5()
hashobj.de('utf-8'))
return hashobj.hexdigest()
def sendMail(text):
mail_info = get_conf()
sender = mail_info['sender']
receiver = mail_info['receiver']
subject = '[AutomationTest]接⼝⾃动化测试报告通知'
smtpserver = mail_info['smtpserver']
username = mail_info['username']
password = mail_info['password']
msg = MIMEText(text,'html','utf-8')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = ''.join(receiver)
smtp = smtplib.SMTP()
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()
def main():
errorTest = runTest('TestCase/TestCase.xlsx')
if len(errorTest) > 0:
html = '<html><body>接⼝⾃动化扫描,共有 ' + str(len(errorTest)) + ' 个异常接⼝,列表如下:' + '</p>
<table><tr><th >接⼝</th><th >状态</th><th text-align:left">' + test[0] + '</td><td >' + test[1] + '</td><td >' + test[2] + '</td><td >' + test[3] + '</td></tr>'
sendMail(html)
if __name__ == '__main__':
main()
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论