diff --git a/httprunner/compat.py b/httprunner/compat.py index 91308ec2..9bb21574 100644 --- a/httprunner/compat.py +++ b/httprunner/compat.py @@ -5,6 +5,7 @@ This module handles compatibility issues between testcase format v2 and v3. from typing import List, Dict, Text, Union from httprunner import exceptions +from httprunner.utils import sort_dict_by_custom_order def convert_jmespath(raw: Text) -> Text: @@ -57,7 +58,6 @@ def convert_extractors(extractors: Union[List, Dict]) -> Dict: 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} @@ -71,8 +71,33 @@ def convert_validators(validators: List) -> List: return validators -def ensure_step_attachment(step: Dict) -> Dict: +def sort_request_by_custom_order(request: Dict) -> Dict: + custom_order = [ + "method", + "url", + "params", + "headers", + "cookies", + "data", + "json", + "files", + "timeout", + "allow_redirects", + "proxies", + "verify", + "stream", + "auth", + "cert", + ] + return sort_dict_by_custom_order(request, custom_order) + +def sort_step_by_custom_order(step: Dict) -> Dict: + custom_order = ["name", "variables", "request", "testcase", "extract", "validate"] + return sort_dict_by_custom_order(step, custom_order) + + +def ensure_step_attachment(step: Dict) -> Dict: test_dict = { "name": step["name"], } @@ -90,12 +115,13 @@ def ensure_step_attachment(step: Dict) -> Dict: def ensure_testcase_v3_api(api_content: Dict) -> Dict: - teststep = { "request": api_content["request"], } teststep.update(ensure_step_attachment(api_content)) + teststep = sort_step_by_custom_order(teststep) + return { "config": {"name": api_content["name"]}, "teststeps": [teststep], @@ -103,7 +129,6 @@ def ensure_testcase_v3_api(api_content: Dict) -> Dict: def ensure_testcase_v3(test_content: Dict) -> Dict: - v3_content = {"config": test_content["config"], "teststeps": []} for step in test_content["teststeps"]: @@ -117,6 +142,7 @@ def ensure_testcase_v3(test_content: Dict) -> Dict: teststep["testcase"] = step.pop("testcase") teststep.update(ensure_step_attachment(step)) + teststep = sort_step_by_custom_order(teststep) v3_content["teststeps"].append(teststep) return v3_content diff --git a/httprunner/ext/har2case/core_test.py b/httprunner/ext/har2case/core_test.py index 22ec06e4..47cef5d1 100644 --- a/httprunner/ext/har2case/core_test.py +++ b/httprunner/ext/har2case/core_test.py @@ -2,10 +2,10 @@ import os from httprunner.ext.har2case.core import HarParser from httprunner.ext.har2case.utils import load_har_log_entries -from httprunner.ext.har2case.utils_test import TestUtils +from httprunner.ext.har2case.utils_test import TestHar2CaseUtils -class TestHar(TestUtils): +class TestHar(TestHar2CaseUtils): def setUp(self): self.har_path = os.path.join(os.path.dirname(__file__), "data", "demo.har") self.har_parser = HarParser(self.har_path) diff --git a/httprunner/ext/har2case/utils_test.py b/httprunner/ext/har2case/utils_test.py index 38e34dd5..658ec3ae 100644 --- a/httprunner/ext/har2case/utils_test.py +++ b/httprunner/ext/har2case/utils_test.py @@ -5,7 +5,7 @@ import unittest from httprunner.ext.har2case import utils -class TestUtils(unittest.TestCase): +class TestHar2CaseUtils(unittest.TestCase): @staticmethod def create_har_file(file_name, content): file_path = os.path.join( @@ -24,7 +24,7 @@ class TestUtils(unittest.TestCase): self.assertIn("response", log_entries[0]) def test_load_har_log_key_error(self): - empty_json_file_path = TestUtils.create_har_file( + empty_json_file_path = TestHar2CaseUtils.create_har_file( file_name="empty_json", content={} ) with self.assertRaises(SystemExit): @@ -32,7 +32,9 @@ class TestUtils(unittest.TestCase): os.remove(empty_json_file_path) def test_load_har_log_empty_error(self): - empty_file_path = TestUtils.create_har_file(file_name="empty", content="") + empty_file_path = TestHar2CaseUtils.create_har_file( + file_name="empty", content="" + ) with self.assertRaises(SystemExit): utils.load_har_log_entries(empty_file_path) os.remove(empty_file_path) diff --git a/httprunner/ext/scaffold/scaffold_test.py b/httprunner/ext/scaffold/scaffold_test.py index b85c1d48..9f7b049a 100644 --- a/httprunner/ext/scaffold/scaffold_test.py +++ b/httprunner/ext/scaffold/scaffold_test.py @@ -6,7 +6,7 @@ import unittest from httprunner.ext.scaffold import create_scaffold -class TestUtils(unittest.TestCase): +class TestScaffold(unittest.TestCase): def test_create_scaffold(self): project_name = "projectABC" create_scaffold(project_name) diff --git a/httprunner/utils.py b/httprunner/utils.py index a3c97651..d035b3d6 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -2,6 +2,7 @@ import collections import json import os.path import platform +from typing import Dict, List, Any from loguru import logger @@ -151,3 +152,16 @@ def get_platform(): ), "platform": platform.platform(), } + + +def sort_dict_by_custom_order(raw_dict: Dict, custom_order: List): + def get_index_from_list(lst: List, item: Any): + try: + return lst.index(item) + except ValueError: + # item is not in lst + return len(lst) + 1 + + return dict( + sorted(raw_dict.items(), key=lambda i: get_index_from_list(custom_order, i[0])) + ) diff --git a/httprunner/utils_test.py b/httprunner/utils_test.py index 252b33f0..6558325c 100644 --- a/httprunner/utils_test.py +++ b/httprunner/utils_test.py @@ -1,4 +1,3 @@ -import io import os import unittest @@ -89,3 +88,13 @@ class TestUtils(unittest.TestCase): def test_print_info(self): info_mapping = {"a": 1, "t": (1, 2), "b": {"b1": 123}, "c": None, "d": [4, 5]} utils.print_info(info_mapping) + + def test_sort_dict_by_custom_order(self): + self.assertEqual( + list( + utils.sort_dict_by_custom_order( + {"C": 3, "D": 2, "A": 1, "B": 8}, ["A", "D"] + ).keys() + ), + ["A", "D", "C", "B"], + )