httprunner2.x--用例中提取数据:delimiter 界定符方式源码解读
在 HttpRunner 中提取数据时,根据界定符的方式进行提取,涉及到的内容包括如下:
["status_code", "encoding", "ok", "reason", "url"]
cookies
elapsed
headers
["content", "text", "json"]
从源码角度分析 httprunner\httprunner\response.py:
def _extract_field_with_delimiter(self, field): """ response content could be json or html text. Args: field (str): string joined by delimiter. e.g. "status_code" "headers" "cookies" "content" "headers.content-type" "content.person.name.first_name" """ # string.split(sep=None, maxsplit=1) -> list of strings # e.g. "content.person.name" => ["content", "person.name"] try: top_query, sub_query = field.split('.', 1) except ValueError: top_query = field sub_query = None # status_code # 1.......如果是顶级项,提取数据的目标区域为列表中的内容 if top_query in ["status_code", "encoding", "ok", "reason", "url"]: # 如果有子项,返回子项 if sub_query: # status_code.XX # 子项的取值 err_msg = u"Failed to extract: {}\n".format(field) logger.log_error(err_msg) raise exceptions.ParamsError(err_msg) # 没有子项返回 顶级项 return getattr(self, top_query) # cookies # 2...提取数据的目标区域为cookies elif top_query == "cookies": cookies = self.cookies # 如果没有子项,返回全部cookies内容(cookies有可能多个) if not sub_query: # extract cookies return cookies try: # 如果有子项,返回指定子项 return cookies[sub_query] except KeyError: err_msg = u"Failed to extract cookie! => {}\n".format(field) err_msg += u"response cookies: {}\n".format(cookies) logger.log_error(err_msg) raise exceptions.ExtractFailure(err_msg) # elapsed # 3.....提取数据的目标为相应时间 elif top_query == "elapsed": # 支持的时间格式 available_attributes = u"available attributes: days, seconds, microseconds, total_seconds" if not sub_query: err_msg = u"elapsed is datetime.timedelta instance, attribute should also be specified!\n" err_msg += available_attributes logger.log_error(err_msg) raise exceptions.ParamsError(err_msg) # 以天,秒,微秒为子项 elif sub_query in ["days", "seconds", "microseconds"]: return getattr(self.elapsed, sub_query) # 以总秒为子项 elif sub_query == "total_seconds": return self.elapsed.total_seconds() else: err_msg = "{} is not valid datetime.timedelta attribute.\n".format(sub_query) err_msg += available_attributes logger.log_error(err_msg) raise exceptions.ParamsError(err_msg) # headers # 4....提取数据的目标为相应头部区域 elif top_query == "headers": headers = self.headers # 如果没有子项,返回整个头域 if not sub_query: # extract headers return headers try: # 如果有子项,返回头域中该子项的值 return headers[sub_query] except KeyError: err_msg = u"Failed to extract header! => {}\n".format(field) err_msg += u"response headers: {}\n".format(headers) logger.log_error(err_msg) raise exceptions.ExtractFailure(err_msg) # response body # 如果顶级项为列表中内容 elif top_query in ["content", "text", "json"]: try: # 返回json类型响应实体 body = self.json except exceptions.JSONDecodeError: # 如果响应实体不是json类型,则返回text类型 body = self.text if not sub_query: # extract response body # 如果没有子项,返回整个实体内容 return body # 如果实体属于dict或list类型 if isinstance(body, (dict, list)): # content = {"xxx": 123}, content.xxx # 返回子项对应的值 return utils.query_json(body, sub_query) elif sub_query.isdigit(): # content = "abcdefg", content.3 => d # 如果子项是数字,返回该数字序号位置的字符串 return utils.query_json(body, sub_query) else: # content = "<html>abcdefg</html>", content.xxx err_msg = u"Failed to extract attribute from response body! => {}\n".format(field) err_msg += u"response body: {}\n".format(body) logger.log_error(err_msg) raise exceptions.ExtractFailure(err_msg) # new set response attributes in teardown_hooks elif top_query in self.__dict__: attributes = self.__dict__[top_query] if not sub_query: # extract response attributes return attributes if isinstance(attributes, (dict, list)): # attributes = {"xxx": 123}, content.xxx return utils.query_json(attributes, sub_query) elif sub_query.isdigit(): # attributes = "abcdefg", attributes.3 => d return utils.query_json(attributes, sub_query) else: # content = "attributes.new_attribute_not_exist" err_msg = u"Failed to extract cumstom set attribute from teardown hooks! => {}\n".format(field) err_msg += u"response set attributes: {}\n".format(attributes) logger.log_error(err_msg) raise exceptions.TeardownHooksFailure(err_msg) # others else: err_msg = u"Failed to extract attribute from response! => {}\n".format(field) err_msg += u"available response attributes: status_code, cookies, elapsed, headers, content, text, json, encoding, ok, reason, url.\n\n" err_msg += u"If you want to set attribute in teardown_hooks, take the following example as reference:\n" err_msg += u"response.new_attribute = 'new_attribute_value'\n" logger.log_error(err_msg) raise exceptions.ParamsError(err_msg)