diff --git a/httprunner/client.py b/httprunner/client.py index 0f9e4d9a..1a6c1af6 100644 --- a/httprunner/client.py +++ b/httprunner/client.py @@ -1,20 +1,17 @@ # encoding: utf-8 -import re import time import requests import urllib3 from httprunner import logger -from httprunner.exceptions import ParamsError +from httprunner.utils import build_url from requests import Request, Response from requests.exceptions import (InvalidSchema, InvalidURL, MissingSchema, RequestException) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -absolute_http_url_regexp = re.compile(r"^https?://", re.I) - class ApiResponse(Response): @@ -42,15 +39,6 @@ class HttpSession(requests.Session): self.base_url = base_url if base_url else "" self.init_meta_data() - def _build_url(self, path): - """ prepend url with hostname unless it's already an absolute URL """ - if absolute_http_url_regexp.match(path): - return path - elif self.base_url: - return "{}/{}".format(self.base_url.rstrip("/"), path.lstrip("/")) - else: - raise ParamsError("base url missed!") - def init_meta_data(self): """ initialize meta_data, it will store detail data of request and response """ @@ -125,7 +113,7 @@ class HttpSession(requests.Session): self.meta_data["request"]["start_timestamp"] = time.time() # prepend url with hostname unless it's already an absolute URL - url = self._build_url(url) + url = build_url(self.base_url, url) kwargs.setdefault("timeout", 120) response = self._send_request_safe_mode(method, url, **kwargs) diff --git a/httprunner/parser.py b/httprunner/parser.py index 63aac7d8..e764b048 100644 --- a/httprunner/parser.py +++ b/httprunner/parser.py @@ -609,9 +609,12 @@ def _extend_with_api(teststep_dict, api_def_dict): # TODO: merge & override request teststep_dict["request"] = api_def_dict.pop("request", {}) # base_url - base_url = teststep_dict.pop("base_url", None) - if base_url: - teststep_dict["request"]["url"] = "{}/{}".format(base_url.rstrip("/"), teststep_dict["request"]["url"].lstrip("/")) + if "base_url" in teststep_dict: + base_url = teststep_dict.pop("base_url") + teststep_dict["request"]["url"] = utils.build_url( + base_url, + teststep_dict["request"]["url"] + ) # verify if "verify" in teststep_dict: @@ -744,8 +747,9 @@ def __parse_teststeps(teststeps, config, project_mapping): for teststep in teststeps: - # priority teststep > config - teststep.setdefault("base_url", config_base_url) + # base_url & verify: priority teststep > config + if config_base_url: + teststep.setdefault("base_url", config_base_url) teststep.setdefault("verify", config_verify) if "testcase_def" in teststep: @@ -776,6 +780,10 @@ def __parse_teststeps(teststeps, config, project_mapping): _parse_testcase(teststep, project_mapping) else: + # teststep is API test, has two cases. + # (1) teststep has API reference + # (2) teststep is defined directly + # 1, config => teststeps # override teststep variables teststep["variables"] = utils.extend_variables( @@ -794,14 +802,18 @@ def __parse_teststeps(teststeps, config, project_mapping): pass if "api_def" in teststep: + # case (1) # 2, teststep => api api_def_dict = teststep.pop("api_def") _extend_with_api(teststep, api_def_dict) else: - # base_url - base_url = teststep.pop("base_url", None) - if base_url: - teststep["request"]["url"] = "{}/{}".format(base_url.rstrip("/"), teststep["request"]["url"].lstrip("/")) + # case (2) + if "base_url" in teststep: + base_url = teststep.pop("base_url") + teststep["request"]["url"] = utils.build_url( + base_url, + teststep["request"]["url"] + ) def _parse_testcase(testcase, project_mapping): diff --git a/httprunner/utils.py b/httprunner/utils.py index dfea2059..069b6272 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -6,11 +6,15 @@ import io import itertools import json import os.path +import re import string from datetime import datetime from httprunner import exceptions, logger from httprunner.compat import OrderedDict, basestring, is_py2 +from httprunner.exceptions import ParamsError + +absolute_http_url_regexp = re.compile(r"^https?://", re.I) def set_os_environ(variables_mapping): @@ -48,6 +52,16 @@ def get_os_environ(variable_name): raise exceptions.EnvNotFound(variable_name) +def build_url(base_url, path): + """ prepend url with hostname unless it's already an absolute URL """ + if absolute_http_url_regexp.match(path): + return path + elif base_url: + return "{}/{}".format(base_url.rstrip("/"), path.lstrip("/")) + else: + raise ParamsError("base url missed!") + + def query_json(json_content, query, delimiter='.'): """ Do an xpath-like query with json_content. @param (dict/list/string) json_content