我正在使用 Python 测试 REST API。我收到一条 json 格式的响应消息,并想检查每个字段。我创建了一个 check_json 函数并对照检查器字典进行检查。检查器字典有一个字符串键,它是 json 中键的名称,其值为一个带有第一个 bool 参数的元组(一对),项目是否是强制性的,第二个参数是进行直接比较的对象还是添加更多涉及的函数检查功能。
我这样检查:
r= check_json(myjson, checker)
其中 r 是格式的结果:'field':True 或 False - 取决于检查是通过还是失败
代码有点乱,有很多全局函数。一个想法是在 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)