fix: ensure compatibility issues between testcase format v2 and v3

This commit is contained in:
debugtalk
2020-05-27 18:52:45 +08:00
parent c2241346e5
commit 81608b3bd5
4 changed files with 98 additions and 10 deletions

View File

@@ -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
View 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

View File

@@ -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:

View File

@@ -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]}