mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-02 22:39:42 +08:00
feat: run test with reference testcase
This commit is contained in:
@@ -29,7 +29,7 @@ class {{ class_name }}(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
def make_testcase(testcase_path: str) -> str:
|
def make_testcase(testcase_path: str) -> str:
|
||||||
testcase = load_testcase_file(testcase_path)
|
testcase, _ = load_testcase_file(testcase_path)
|
||||||
template = jinja2.Template(__TMPL__)
|
template = jinja2.Template(__TMPL__)
|
||||||
|
|
||||||
raw_file_name, _ = os.path.splitext(os.path.basename(testcase_path))
|
raw_file_name, _ = os.path.splitext(os.path.basename(testcase_path))
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ import json
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
from typing import Tuple, Dict
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from httprunner import builtin, utils
|
from httprunner import builtin, utils
|
||||||
from httprunner import exceptions
|
from httprunner import exceptions
|
||||||
from httprunner.schema import TestCase
|
from httprunner.schema import TestCase, ProjectMeta
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# PyYAML version >= 5.1
|
# PyYAML version >= 5.1
|
||||||
@@ -47,7 +48,7 @@ def _load_json_file(json_file):
|
|||||||
return json_content
|
return json_content
|
||||||
|
|
||||||
|
|
||||||
def load_testcase_file(testcase_file):
|
def load_testcase_file(testcase_file) -> Tuple[Dict, TestCase]:
|
||||||
"""load testcase file and validate with pydantic model"""
|
"""load testcase file and validate with pydantic model"""
|
||||||
file_suffix = os.path.splitext(testcase_file)[1].lower()
|
file_suffix = os.path.splitext(testcase_file)[1].lower()
|
||||||
if file_suffix == ".json":
|
if file_suffix == ".json":
|
||||||
@@ -61,9 +62,10 @@ def load_testcase_file(testcase_file):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# validate with pydantic TestCase model
|
# validate with pydantic TestCase model
|
||||||
TestCase.parse_obj(testcase_content)
|
testcase_obj = TestCase.parse_obj(testcase_content)
|
||||||
|
testcase_obj.config.path = testcase_file
|
||||||
|
|
||||||
return testcase_content
|
return testcase_content, testcase_obj
|
||||||
|
|
||||||
|
|
||||||
def load_dot_env_file(dot_env_path):
|
def load_dot_env_file(dot_env_path):
|
||||||
@@ -302,7 +304,7 @@ def load_debugtalk_functions():
|
|||||||
return load_module_functions(imported_module)
|
return load_module_functions(imported_module)
|
||||||
|
|
||||||
|
|
||||||
def load_project_data(test_path: str, dot_env_path: str = None):
|
def load_project_data(test_path: str, dot_env_path: str = None) -> ProjectMeta:
|
||||||
""" load api, testcases, .env, debugtalk.py functions.
|
""" load api, testcases, .env, debugtalk.py functions.
|
||||||
api/testcases folder is relative to project_working_directory
|
api/testcases folder is relative to project_working_directory
|
||||||
|
|
||||||
@@ -311,7 +313,7 @@ def load_project_data(test_path: str, dot_env_path: str = None):
|
|||||||
dot_env_path (str): specified .env file path
|
dot_env_path (str): specified .env file path
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: project loaded api/testcases definitions,
|
project loaded api/testcases definitions,
|
||||||
environments and debugtalk.py functions.
|
environments and debugtalk.py functions.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -341,4 +343,4 @@ def load_project_data(test_path: str, dot_env_path: str = None):
|
|||||||
len(project_working_directory) + 1 :
|
len(project_working_directory) + 1 :
|
||||||
]
|
]
|
||||||
|
|
||||||
return project_meta
|
return ProjectMeta.parse_obj(project_meta)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
from typing import List, Dict
|
from typing import List, Dict
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -5,7 +6,7 @@ from loguru import logger
|
|||||||
from httprunner import utils, exceptions
|
from httprunner import utils, exceptions
|
||||||
from httprunner.client import HttpSession
|
from httprunner.client import HttpSession
|
||||||
from httprunner.exceptions import ValidationFailure, ParamsError
|
from httprunner.exceptions import ValidationFailure, ParamsError
|
||||||
from httprunner.new_loader import load_project_data
|
from httprunner.new_loader import load_project_data, load_testcase_file
|
||||||
from httprunner.parser import build_url, parse_data, parse_variables_mapping
|
from httprunner.parser import build_url, parse_data, parse_variables_mapping
|
||||||
from httprunner.response import ResponseObject
|
from httprunner.response import ResponseObject
|
||||||
from httprunner.schema import (
|
from httprunner.schema import (
|
||||||
@@ -17,8 +18,15 @@ from httprunner.schema import (
|
|||||||
|
|
||||||
|
|
||||||
class TestCaseRunner(object):
|
class TestCaseRunner(object):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
config: TestsConfig,
|
||||||
|
teststeps: List[TestStep],
|
||||||
|
session: HttpSession = None,
|
||||||
|
):
|
||||||
|
if not config.path:
|
||||||
|
raise exceptions.ParamsError("config path missed!")
|
||||||
|
|
||||||
def __init__(self, config: TestsConfig, teststeps: List[TestStep], session: HttpSession = None):
|
|
||||||
self.config = config
|
self.config = config
|
||||||
self.teststeps = teststeps
|
self.teststeps = teststeps
|
||||||
self.session = session
|
self.session = session
|
||||||
@@ -27,6 +35,9 @@ class TestCaseRunner(object):
|
|||||||
self.session_variables: Dict = {}
|
self.session_variables: Dict = {}
|
||||||
self.success: bool = True # indicate testcase execution result
|
self.success: bool = True # indicate testcase execution result
|
||||||
|
|
||||||
|
self.project_data = load_project_data(self.config.path)
|
||||||
|
self.config.functions = self.project_data.functions
|
||||||
|
|
||||||
def with_variables(self, **variables: VariablesMapping) -> "TestCaseRunner":
|
def with_variables(self, **variables: VariablesMapping) -> "TestCaseRunner":
|
||||||
self.config.variables.update(variables)
|
self.config.variables.update(variables)
|
||||||
return self
|
return self
|
||||||
@@ -109,8 +120,15 @@ class TestCaseRunner(object):
|
|||||||
"""run teststep: referenced testcase"""
|
"""run teststep: referenced testcase"""
|
||||||
step_data = StepData(name=step.name)
|
step_data = StepData(name=step.name)
|
||||||
step_variables = step.variables
|
step_variables = step.variables
|
||||||
testcase: TestCaseRunner = step.testcase() # TODO: fix
|
|
||||||
case_result = testcase.with_variables(**step_variables).run()
|
ref_testcase_path = os.path.join(self.project_data.PWD, step.testcase)
|
||||||
|
_, testcase_obj = load_testcase_file(ref_testcase_path)
|
||||||
|
|
||||||
|
case_result = (
|
||||||
|
TestCaseRunner(testcase_obj.config, testcase_obj.teststeps, self.session)
|
||||||
|
.with_variables(**step_variables)
|
||||||
|
.run()
|
||||||
|
)
|
||||||
step_data.data = case_result.step_datas # list of step data
|
step_data.data = case_result.step_datas # list of step data
|
||||||
step_data.export = case_result.get_export_variables()
|
step_data.export = case_result.get_export_variables()
|
||||||
step_data.success = case_result.success
|
step_data.success = case_result.success
|
||||||
@@ -136,12 +154,6 @@ class TestCaseRunner(object):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""main entrance"""
|
"""main entrance"""
|
||||||
if not self.config.path:
|
|
||||||
raise exceptions.ParamsError("config path missed!")
|
|
||||||
|
|
||||||
project_data = load_project_data(self.config.path)
|
|
||||||
self.config.functions = project_data["functions"]
|
|
||||||
|
|
||||||
self.step_datas.clear()
|
self.step_datas.clear()
|
||||||
self.session_variables.clear()
|
self.session_variables.clear()
|
||||||
for step in self.teststeps:
|
for step in self.teststeps:
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class Request(BaseModel):
|
|||||||
class TestStep(BaseModel):
|
class TestStep(BaseModel):
|
||||||
name: Name
|
name: Name
|
||||||
request: Request = None
|
request: Request = None
|
||||||
testcase: Union[Text, Callable] = None
|
testcase: Text = ""
|
||||||
variables: VariablesMapping = {}
|
variables: VariablesMapping = {}
|
||||||
extract: Dict[Text, Text] = {}
|
extract: Dict[Text, Text] = {}
|
||||||
validators: Validators = Field([], alias="validate")
|
validators: Validators = Field([], alias="validate")
|
||||||
|
|||||||
Reference in New Issue
Block a user