mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 15:37:35 +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: ensure converted python file in utf-8 encoding
|
||||||
- fix: duplicate running referenced testcase
|
- fix: duplicate running referenced testcase
|
||||||
|
- fix: ensure compatibility issues between testcase format v2 and v3
|
||||||
|
|
||||||
## 3.0.5 (2020-05-22)
|
## 3.0.5 (2020-05-22)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
from typing import Text, List, Tuple, Dict, Set, NoReturn
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
from loguru import logger
|
|
||||||
|
|
||||||
from httprunner import exceptions
|
from httprunner import exceptions
|
||||||
|
from httprunner.compat import ensure_testcase_v3_api, ensure_testcase_v3
|
||||||
from httprunner.loader import (
|
from httprunner.loader import (
|
||||||
load_folder_files,
|
load_folder_files,
|
||||||
load_test_file,
|
load_test_file,
|
||||||
@@ -14,6 +13,7 @@ from httprunner.loader import (
|
|||||||
load_project_meta,
|
load_project_meta,
|
||||||
)
|
)
|
||||||
from httprunner.parser import parse_data
|
from httprunner.parser import parse_data
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
""" cache converted pytest files, avoid duplicate making
|
""" 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:
|
def __make_testcase(testcase: Dict, dir_path: Text = None) -> NoReturn:
|
||||||
"""convert valid testcase dict to pytest file path"""
|
"""convert valid testcase dict to pytest file path"""
|
||||||
try:
|
# ensure compatibility with testcase format v2
|
||||||
# validate testcase format
|
testcase = ensure_testcase_v3(testcase)
|
||||||
load_testcase(testcase)
|
|
||||||
except exceptions.TestCaseFormatError as ex:
|
# validate testcase format
|
||||||
logger.error(f"TestCaseFormatError: {ex}")
|
load_testcase(testcase)
|
||||||
raise
|
|
||||||
|
|
||||||
testcase_path = __ensure_absolute(testcase["config"]["path"])
|
testcase_path = __ensure_absolute(testcase["config"]["path"])
|
||||||
logger.info(f"start to make testcase: {testcase_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:
|
for test_file in test_files:
|
||||||
try:
|
try:
|
||||||
test_content = load_test_file(test_file)
|
test_content = load_test_file(test_file)
|
||||||
test_content.setdefault("config", {})["path"] = test_file
|
|
||||||
except (exceptions.FileNotFound, exceptions.FileFormatError) as ex:
|
except (exceptions.FileNotFound, exceptions.FileFormatError) as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
continue
|
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
|
# testcase
|
||||||
if "teststeps" in test_content:
|
if "teststeps" in test_content:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ def uniform_validator(validator):
|
|||||||
Args:
|
Args:
|
||||||
validator (dict): validator maybe in two formats:
|
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": "status_code", "assert": "eq", "expect": 201}
|
||||||
{"check": "$resp_body_success", "assert": "eq", "expect": True}
|
{"check": "$resp_body_success", "assert": "eq", "expect": True}
|
||||||
format2: recommended new version, {assert: [check_item, expected_value]}
|
format2: recommended new version, {assert: [check_item, expected_value]}
|
||||||
|
|||||||
Reference in New Issue
Block a user