mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-15 04:19:28 +08:00
fix: ensure compatibility issues between testcase format v2 and v3
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
- fix: ensure converted python file in utf-8 encoding
|
||||
- fix: duplicate running referenced testcase
|
||||
- fix: ensure compatibility issues between testcase format v2 and v3
|
||||
|
||||
## 3.0.5 (2020-05-22)
|
||||
|
||||
|
||||
83
httprunner/compat.py
Normal file
83
httprunner/compat.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""
|
||||
This module handles compatibility issues between testcase format v2 and v3.
|
||||
"""
|
||||
|
||||
from typing import List, Dict, Text
|
||||
|
||||
|
||||
def convert_jmespath(raw: Text) -> Text:
|
||||
if raw.startswith("content"):
|
||||
return f"body{raw[len('content'):]}"
|
||||
elif raw.startswith("json"):
|
||||
return f"body{raw[len('json'):]}"
|
||||
|
||||
return raw
|
||||
|
||||
|
||||
def convert_extractors(extractors: List) -> Dict:
|
||||
""" convert extract list(v2) to dict(v3)
|
||||
|
||||
Args:
|
||||
extractors: [{"varA": "content.varA"}, {"varB": "json.varB"}]
|
||||
|
||||
Returns:
|
||||
{"varA": "body.varA", "varB": "body.varB"}
|
||||
|
||||
"""
|
||||
if isinstance(extractors, Dict):
|
||||
return extractors
|
||||
|
||||
v3_extractors = {}
|
||||
for extractor in extractors:
|
||||
for k, v in extractor.items():
|
||||
v3_extractors[k] = convert_jmespath(v)
|
||||
|
||||
return v3_extractors
|
||||
|
||||
|
||||
def convert_validators(validators: List) -> List:
|
||||
|
||||
for v in validators:
|
||||
if "check" in v and "expect" in v:
|
||||
# format1: {"check": "content.abc", "assert": "eq", "expect": 201}
|
||||
v["check"] = convert_jmespath(v["check"])
|
||||
|
||||
elif len(v) == 1:
|
||||
# format2: {'eq': ['status_code', 201]}
|
||||
comparator = list(v.keys())[0]
|
||||
v[comparator][0] = convert_jmespath(v[comparator][0])
|
||||
|
||||
return validators
|
||||
|
||||
|
||||
def ensure_testcase_v3_api(api_content: Dict) -> Dict:
|
||||
|
||||
return {
|
||||
"config": {"name": api_content["name"]},
|
||||
"teststeps": [
|
||||
{
|
||||
"name": api_content["name"],
|
||||
"variables": api_content.get("variables", {}),
|
||||
"request": api_content["request"],
|
||||
"validate": convert_validators(api_content.get("validate", [])),
|
||||
"extract": convert_extractors(api_content.get("extract", {})),
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def ensure_testcase_v3(test_content: Dict) -> Dict:
|
||||
|
||||
v3_content = {"config": test_content["config"], "teststeps": []}
|
||||
|
||||
for step in test_content["teststeps"]:
|
||||
teststep = {}
|
||||
if "api" in step:
|
||||
teststep["testcase"] = step.pop("api")
|
||||
|
||||
teststep["extract"] = convert_extractors(step.pop("extract", {}))
|
||||
teststep["validate"] = convert_validators(step.pop("validate", []))
|
||||
teststep.update(step)
|
||||
v3_content["teststeps"].append(teststep)
|
||||
|
||||
return v3_content
|
||||
@@ -3,9 +3,8 @@ import subprocess
|
||||
from typing import Text, List, Tuple, Dict, Set, NoReturn
|
||||
|
||||
import jinja2
|
||||
from loguru import logger
|
||||
|
||||
from httprunner import exceptions
|
||||
from httprunner.compat import ensure_testcase_v3_api, ensure_testcase_v3
|
||||
from httprunner.loader import (
|
||||
load_folder_files,
|
||||
load_test_file,
|
||||
@@ -14,6 +13,7 @@ from httprunner.loader import (
|
||||
load_project_meta,
|
||||
)
|
||||
from httprunner.parser import parse_data
|
||||
from loguru import logger
|
||||
|
||||
""" cache converted pytest files, avoid duplicate making
|
||||
"""
|
||||
@@ -109,12 +109,11 @@ def __format_pytest_with_black(python_paths: List[Text]) -> NoReturn:
|
||||
|
||||
def __make_testcase(testcase: Dict, dir_path: Text = None) -> NoReturn:
|
||||
"""convert valid testcase dict to pytest file path"""
|
||||
try:
|
||||
# validate testcase format
|
||||
load_testcase(testcase)
|
||||
except exceptions.TestCaseFormatError as ex:
|
||||
logger.error(f"TestCaseFormatError: {ex}")
|
||||
raise
|
||||
# ensure compatibility with testcase format v2
|
||||
testcase = ensure_testcase_v3(testcase)
|
||||
|
||||
# validate testcase format
|
||||
load_testcase(testcase)
|
||||
|
||||
testcase_path = __ensure_absolute(testcase["config"]["path"])
|
||||
logger.info(f"start to make testcase: {testcase_path}")
|
||||
@@ -255,11 +254,16 @@ def __make(tests_path: Text) -> NoReturn:
|
||||
for test_file in test_files:
|
||||
try:
|
||||
test_content = load_test_file(test_file)
|
||||
test_content.setdefault("config", {})["path"] = test_file
|
||||
except (exceptions.FileNotFound, exceptions.FileFormatError) as ex:
|
||||
logger.warning(ex)
|
||||
continue
|
||||
|
||||
# api in v2 format, convert to v3 testcase
|
||||
if "request" in test_content:
|
||||
test_content = ensure_testcase_v3_api(test_content)
|
||||
|
||||
test_content.setdefault("config", {})["path"] = test_file
|
||||
|
||||
# testcase
|
||||
if "teststeps" in test_content:
|
||||
try:
|
||||
|
||||
@@ -61,7 +61,7 @@ def uniform_validator(validator):
|
||||
Args:
|
||||
validator (dict): validator maybe in two formats:
|
||||
|
||||
format1: this is kept for compatiblity with the previous versions.
|
||||
format1: this is kept for compatibility with the previous versions.
|
||||
{"check": "status_code", "assert": "eq", "expect": 201}
|
||||
{"check": "$resp_body_success", "assert": "eq", "expect": True}
|
||||
format2: recommended new version, {assert: [check_item, expected_value]}
|
||||
|
||||
Reference in New Issue
Block a user