我正在使用Python来测试REST API。我得到一个响应消息为json并且想要检查每个字段。我创建了一个check_json函数,并根据检查字典进行检查。检查器字典中有一个字符串键,它是json中键的名称,其值是一个带有第一个bool参数的元组(一对),是否为必需项,第二个参数是要做直接比较的对象还是添加更多的函数检查功能。如何删除这些检查功能的全局需要
我做检查是这样的:
r= check_json(myjson, checker)
其中r是结果格式:“田”:真或假 - 取决于检查是否通过或失败
的代码是一个小messay具有许多全球功能。一个想法是在check_json中包含检查函数。我被告知我也可以使用闭包。但是如何?
这里是我的代码:
# check nested json
import json
import collections
import functools
import datetime
#this is json from GET session
myjson = {
"accessed": "Wed, 31 Jul 2013 13:03:38 GMT",
"created": "Wed, 31 Jul 2013 13:03:38 GMT",
"dnUrls": [
"http://135.86.180.69:8580/ucc/api/v1/session/dns/50000"
],
"expires": "Wed, 31 Jul 2013 13:03:48 GMT",
"modified": "Wed, 31 Jul 2013 13:03:38 GMT",
"name": "KW50000",
"person": {
"employeeId": "KW50000",
"firstName": "KW50000",
"lastName": "Dev5"
},
"previewRedirect": {
"destination": "",
"enabled": False,
"setupEnabled": False
}
}
def isDate(s):
try:
testdate = datetime.datetime.strptime(s, '%a, %d %b %Y %H:%M:%S GMT')
return True
except Exception:
print "conversion to date failed"
return False
def isURL(l):
count = 0
for item in l:
count += 1 if item.startswith("http://") else (-1)
return count > 0
def isAlnum(s):
return s.isalnum()
def isBool(s):
return type(s) == bool
def isAny(s):
return True
#checker object made up of dictionary with string key and tuple value (a pair)
#tuple first filed is flag indicating whether key is mandatory or not.
# tuple 2nd key is value to expect or a checker function
checker = {
"accessed": (True, isDate),
"created": (True, isDate),
"dnUrls": (True, isURL),
"expires": (True, isDate),
"modified": (True, isDate),
"name": (True, "KW50000"),
"person": (True, {
"employeeId": (True, isAlnum),
"firstName": (False, isAny),
"lastName": (False, isAny)
}),
"previewRedirect": (True, {
"destination": (False, isAny),
"enabled": (True, isBool),
"setupEnabled": (False, isBool)
})
}
# returns dictionary with key= fieldname, value = result, either True (Test Pass), False (test Failed)
def check_json(obj, checker):
"""params json to check, template comparison object
returns dictionary of keys to pass/fail values"""
result = {}
for k, (mFlag, chk) in checker.iteritems():
if not k in obj:
result[k] = not mFlag
elif isinstance(chk, collections.Callable):
result[k] = chk(obj[k])
elif(isinstance(chk, collections.Mapping)):
result[k] = check_json(obj[k], chk)
else:
result[k] = chk == obj[k]
return result
def with_and(v1, v2):
return functools.reduce(with_and, v2.itervalues(), v1) if isinstance(v2, collections.Mapping) else v1 and v2
r= check_json(myjson, checker)
print "r={}".format(r)
isOK = functools.reduce(with_and, r.itervalues(), True)
print "Result is {}: {}".format(isOK, r)
你可能可以做一些事情,比如在函数内部创建检查器模板,并在调用或修改“with”语句之前[改变它的命名空间](http://stackoverflow.com/q/1142068/646543)以某种方式提供这些功能并在其中创建模板功能。这种方法可能最终会变得更加混乱和更多的工作,然后它是值得的。 – Michael0x2a