写接口的时候需要对接口进行测试,一般会选用postman这种工具,但是需要一个一个的用鼠标去点他,尤其有些返回值需要手动去更新就更麻烦了,使用脚本自动去测试可以减轻一定的工作量.反正闲着也是闲着,在代码开发的同时脚本也能基本写完了.
我在写接口的时候的基本任务是:登陆获取登陆后的token通过json返回,使用token进行后续的操作
问题1传递数据进行登陆
我们是使用json进行传递的数据,最开始只传递一个类似
jsonStr:{'mobile':'13312345678','pwd':'password'}
这样我需要自己编写head头,并提交获得response
def getResponse(url, val):
json = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n " \#数据的分界线,一个数据一个
"Content-Disposition: form-data; name=\"jsonStr\"" \#jsonStr就是key的键值,和Java代码中的那个是对应的,使用getJsonStr获得
"\r\n\r\n%s\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--" % val#结束符号多了2个'--'
head = {#头记录数据类型,分割线标记
'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
'cache-control': "no-cache"
}
#使用urllib2提交并获得request,调用URLopen获得response,我们的返回值就在里面
request = urllib2.Request(url=url, headers=head, data=json)
return urllib2.urlopen(request)
response = getResponse(url, val)
jsObj = response.read()#获得返回的数据,我返回的是json类型的字符串
ret = json.loads(jsObj)#json转换成Python数据
#也许我下次测试的需要的数据就在这个ret中,这个ret是个Python的字典,辣么...我在写下次jsonStr的时候有
#假设ret={'token':'....etc.....','etc':'...'}
data = "jsonStr:{'token':'%(token)s'}" % ret #->>"jsonStr:{'token':'....etc.....'}"
#这样我就可以直接往下写了,不用关心其他的了
后来需求改成,key1:val1,key2:val1这种形式的,之前的那种形式不能使用了,把原来数据改成字典形式太累.
只用修改分割的形式变成
分割线+内容+name1+val1+分割线+内容+name2+val2.....分割线--这个样子就可以了
稍微修改下上面的修改字符串的方式就行,没啥好说的.
原来的val需要稍微多修改点,其实无非就是2次分割,第一次将原来的字符串以','(逗号)进行分割,第二次用':'(冒号)分割,
我是形成类型[[k1,v1],[k2,v2],[k3,v3]]
def split_val(self, val):
sli = val.strip().lstrip('{').rstrip('}').split(',')
f = lambda x: x.strip().split(':')
ret = [f(x) for x in sli]
return ret
#这样就不用修改原来的最讨厌的数据了
#
附上完整代码
import random
import urllib2
import json
import sys
class singleRun:
def __init__(self, url, val, con):
self.__url__ = url
self.__split__flag__ = "------WebKitFormBoundary7MA4YWxkTrZu0gW"
self.__split__end__ = self.__split__flag__ + "--"
self.__json__ = ''
self.__make__(val)
self.__head__ = {
'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
'cache-control': "no-cache",
'postman-token': "df471615-292b-a328-0c06-f3f3e2e795c8"
}
self.__convertInfo__ = con
self.ret = {}
def __str__(self):
return self.__json__
def __one_json__(self, k, v):
return self.__split__flag__ + "\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n" % (k, v)
#再换JSON传递的格式只用把这个函数修改了就好
def __split_val__(self, val):
sli = val.strip().lstrip('{').rstrip('}').split(',')
f = lambda x: x.strip().split(':')
ret = [f(x) for x in sli]
return ret
def __component__(sli):
for i in sli:
if len(i) != 2:
continue
self.__json__ += self.__one_json__(i[0].strip("'").strip('"'), i[1].strip("'").strip('"'))
def __make__(self, val):
sli = self.__split_val__(val)
self.__component__(sli)
self.__json__ += self.__split__end__
def __get_response__(self):
request = urllib2.Request(url=self.__url__, headers=self.__head__, data=self.__json__)
return urllib2.urlopen(request)
def run(self):
self.name = self.__convertInfo__[self.__url__.split('/')[-1]].decode('utf8')
response = self.__get_response__()
jsObj = response.read()
self.ret = json.loads(jsObj)
return ret, jsObj
def err_status(self):
return '200' != str(self.ret.get('status'))
class test_runer:
convertInfo = {'personal': "获取个人信息", 'schedule': "排班"}
def __init__(self, host=r"http://127.0.0.1/"):
self.__json_data__ = []#用列表来保证插入的顺序
self.__host__ = host
def __setitem__(self, pattern, data):
key = self.__host__ + pattern.lstrip('/')
self.__json_data__.append((key, data))#需求在变的时候直接改singleRun处理就行
def run_tests(self):
ret = {}
cnt = 0
for url, json in self.__json_data__:
cnt += 1
if "TOKEN" in ret:
json % ret
try:
single = singleRun(url, json, test_runer.convertInfo, cnt)
ret,js = single.run()
print js
if single.err_status():
print json
except Exception, e:
print e.message
def test_run(mobile='13312341001', pwd='pwd123'):
host = "http://127.0.0.1:8080/"
test_instance = test_runer(host)
test_instance['personal'] = "'token':'%(TOKEN)s', 'data':'shuju', 'pwd':'{0}'".format(pwd)
test_instance['schedule'] = "'token':'%(TOKEN)s', 'month':'201705'"
test_instance.run_tests()
if __name__ == "__main__":
test_run()