mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-12 02:21:29 +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:
|
||||
testcase = load_testcase_file(testcase_path)
|
||||
testcase, _ = load_testcase_file(testcase_path)
|
||||
template = jinja2.Template(__TMPL__)
|
||||
|
||||
raw_file_name, _ = os.path.splitext(os.path.basename(testcase_path))
|
||||
|
||||
@@ -4,13 +4,14 @@ import json
|
||||
import os
|
||||
import sys
|
||||
import types
|
||||
from typing import Tuple, Dict
|
||||
|
||||
import yaml
|
||||
from loguru import logger
|
||||
|
||||
from httprunner import builtin, utils
|
||||
from httprunner import exceptions
|
||||
from httprunner.schema import TestCase
|
||||
from httprunner.schema import TestCase, ProjectMeta
|
||||
|
||||
try:
|
||||
# PyYAML version >= 5.1
|
||||
@@ -47,7 +48,7 @@ def _load_json_file(json_file):
|
||||
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"""
|
||||
file_suffix = os.path.splitext(testcase_file)[1].lower()
|
||||
if file_suffix == ".json":
|
||||
@@ -61,9 +62,10 @@ def load_testcase_file(testcase_file):
|
||||
)
|
||||
|
||||
# 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):
|
||||
@@ -302,7 +304,7 @@ def load_debugtalk_functions():
|
||||
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.
|
||||
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
|
||||
|
||||
Returns:
|
||||
dict: project loaded api/testcases definitions,
|
||||
project loaded api/testcases definitions,
|
||||
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 :
|
||||
]
|
||||
|
||||
return project_meta
|
||||
return ProjectMeta.parse_obj(project_meta)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
from typing import List, Dict
|
||||
|
||||
from loguru import logger
|
||||
@@ -5,7 +6,7 @@ from loguru import logger
|
||||
from httprunner import utils, exceptions
|
||||
from httprunner.client import HttpSession
|
||||
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.response import ResponseObject
|
||||
from httprunner.schema import (
|
||||
@@ -17,8 +18,15 @@ from httprunner.schema import (
|
||||
|
||||
|
||||
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.teststeps = teststeps
|
||||
self.session = session
|
||||
@@ -27,6 +35,9 @@ class TestCaseRunner(object):
|
||||
self.session_variables: Dict = {}
|
||||
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":
|
||||
self.config.variables.update(variables)
|
||||
return self
|
||||
@@ -109,8 +120,15 @@ class TestCaseRunner(object):
|
||||
"""run teststep: referenced testcase"""
|
||||
step_data = StepData(name=step.name)
|
||||
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.export = case_result.get_export_variables()
|
||||
step_data.success = case_result.success
|
||||
@@ -136,12 +154,6 @@ class TestCaseRunner(object):
|
||||
|
||||
def run(self):
|
||||
"""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.session_variables.clear()
|
||||
for step in self.teststeps:
|
||||
|
||||
@@ -61,7 +61,7 @@ class Request(BaseModel):
|
||||
class TestStep(BaseModel):
|
||||
name: Name
|
||||
request: Request = None
|
||||
testcase: Union[Text, Callable] = None
|
||||
testcase: Text = ""
|
||||
variables: VariablesMapping = {}
|
||||
extract: Dict[Text, Text] = {}
|
||||
validators: Validators = Field([], alias="validate")
|
||||
|
||||
Reference in New Issue
Block a user