mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-13 08:59:44 +08:00
fix: run referenced testcase in python
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# NOTE: Generated By HttpRunner v4.0.0-alpha
|
||||
# FROM: basic.yml
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# NOTE: Generated By HttpRunner v4.0.0-alpha
|
||||
# FROM: hooks.yml
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# NOTE: Generated By HttpRunner v4.0.0-alpha
|
||||
# FROM: load_image.yml
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# NOTE: Generated By HttpRunner v4.0.0-alpha
|
||||
# FROM: upload.yml
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# NOTE: Generated By HttpRunner v4.0.0-alpha
|
||||
# FROM: validate.yml
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ def main():
|
||||
)
|
||||
|
||||
subparsers = parser.add_subparsers(help="sub-command help")
|
||||
sub_parser_run = init_parser_run(subparsers)
|
||||
init_parser_run(subparsers)
|
||||
sub_parser_make = init_make_parser(subparsers)
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
|
||||
@@ -5,7 +5,8 @@ import unittest
|
||||
|
||||
import pytest
|
||||
|
||||
from httprunner.cli import main
|
||||
from httprunner import loader
|
||||
from httprunner.cli import main, main_run
|
||||
|
||||
|
||||
class TestCli(unittest.TestCase):
|
||||
@@ -45,8 +46,17 @@ class TestCli(unittest.TestCase):
|
||||
try:
|
||||
os.chdir(os.path.join(cwd, "examples", "postman_echo"))
|
||||
exit_code = pytest.main(
|
||||
["-s", "request_methods/request_with_testcase_reference_test.py",]
|
||||
["-s", "request_methods/request_with_testcase_reference_test.py"]
|
||||
)
|
||||
self.assertEqual(exit_code, 0)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
def test_run_testcase_with_abnormal_path(self):
|
||||
loader.project_meta = None
|
||||
exit_code = main_run(["examples/data/a-b.c/2 3.yml"])
|
||||
self.assertEqual(exit_code, 0)
|
||||
self.assertTrue(os.path.exists("examples/data/a_b_c/__init__.py"))
|
||||
self.assertTrue(os.path.exists("examples/data/debugtalk.py"))
|
||||
self.assertTrue(os.path.exists("examples/data/a_b_c/T1_test.py"))
|
||||
self.assertTrue(os.path.exists("examples/data/a_b_c/T2_3_test.py"))
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import os
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
from typing import Dict, Text, Union, Callable
|
||||
from typing import List
|
||||
from typing import Any, Callable, Dict, List, Text, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import HttpUrl
|
||||
from pydantic import BaseModel, Field, HttpUrl
|
||||
|
||||
Name = Text
|
||||
Url = Text
|
||||
@@ -156,14 +153,14 @@ class SessionData(BaseModel):
|
||||
class StepData(BaseModel):
|
||||
"""teststep data, each step maybe corresponding to one request or one testcase"""
|
||||
|
||||
name: Text = "" # teststep name
|
||||
step_type: Text = "" # teststep type, request or testcase
|
||||
name: Text = "" # teststep name
|
||||
step_type: Text = "" # teststep type, request or testcase
|
||||
success: bool = False
|
||||
data: Union[SessionData, List['StepData']] = None
|
||||
elapsed: float = 0.0 # teststep elapsed time
|
||||
content_size: float = 0 # response content size
|
||||
elapsed: float = 0.0 # teststep elapsed time
|
||||
content_size: float = 0 # response content size
|
||||
export_vars: VariablesMapping = {}
|
||||
attachment: Text = "" # teststep attachment
|
||||
attachment: Text = "" # teststep attachment
|
||||
|
||||
|
||||
StepData.update_forward_refs()
|
||||
|
||||
@@ -2,6 +2,7 @@ import unittest
|
||||
|
||||
import requests
|
||||
|
||||
from httprunner.parser import Parser
|
||||
from httprunner.response import ResponseObject
|
||||
|
||||
|
||||
@@ -18,15 +19,16 @@ class TestResponse(unittest.TestCase):
|
||||
]
|
||||
},
|
||||
)
|
||||
self.resp_obj = ResponseObject(resp)
|
||||
parser = Parser(functions_mapping={
|
||||
'get_name': lambda: 'name',
|
||||
"get_num": lambda x: x
|
||||
})
|
||||
self.resp_obj = ResponseObject(resp, parser)
|
||||
|
||||
def test_extract(self):
|
||||
variables_mapping = {
|
||||
'body': 'body'
|
||||
}
|
||||
functions_mapping = {
|
||||
'get_name': lambda: 'name',
|
||||
}
|
||||
extract_mapping = self.resp_obj.extract(
|
||||
{
|
||||
"var_1": "body.json.locations[0]",
|
||||
@@ -35,7 +37,6 @@ class TestResponse(unittest.TestCase):
|
||||
"var_4": "$body.json.locations[3].${get_name()}",
|
||||
},
|
||||
variables_mapping=variables_mapping,
|
||||
functions_mapping=functions_mapping,
|
||||
)
|
||||
self.assertEqual(extract_mapping["var_1"], {"name": "Seattle", "state": "WA"})
|
||||
self.assertEqual(extract_mapping["var_2"], "Olympia")
|
||||
@@ -62,9 +63,7 @@ class TestResponse(unittest.TestCase):
|
||||
|
||||
def test_validate_functions(self):
|
||||
variables_mapping = {"index": 1}
|
||||
functions_mapping = {"get_num": lambda x: x}
|
||||
self.resp_obj.validate(
|
||||
[{"eq": ["${get_num(0)}", 0]}, {"eq": ["${get_num($index)}", 1]},],
|
||||
variables_mapping=variables_mapping,
|
||||
functions_mapping=functions_mapping,
|
||||
)
|
||||
|
||||
@@ -16,9 +16,10 @@ from loguru import logger
|
||||
from httprunner.client import HttpSession
|
||||
from httprunner.config import Config
|
||||
from httprunner.exceptions import ParamsError
|
||||
from httprunner.loader import load_project_meta
|
||||
from httprunner.models import (ProjectMeta, StepData, TConfig, TestCaseInOut,
|
||||
TestCaseSummary, TestCaseTime, VariablesMapping)
|
||||
from httprunner.loader import load_project_meta, load_testcase_file
|
||||
from httprunner.models import (ProjectMeta, StepData, TConfig, TestCase,
|
||||
TestCaseInOut, TestCaseSummary, TestCaseTime,
|
||||
VariablesMapping)
|
||||
from httprunner.parser import Parser
|
||||
from httprunner.utils import merge_variables
|
||||
|
||||
@@ -175,11 +176,9 @@ class HttpRunner(object):
|
||||
|
||||
logger.info(f"run step end: {step.name()} <<<<<<\n")
|
||||
|
||||
def test_start(self, param: Dict = None):
|
||||
def test_start(self, param: Dict = None) -> "HttpRunner":
|
||||
"""main entrance, discovered by pytest"""
|
||||
self.__init()
|
||||
log_handler = logger.add(self.__log_path, level="DEBUG")
|
||||
|
||||
self.__parse_config(param)
|
||||
|
||||
if USE_ALLURE:
|
||||
@@ -191,6 +190,7 @@ class HttpRunner(object):
|
||||
f"Start to run testcase: {self.__config.name}, TestCase ID: {self.case_id}"
|
||||
)
|
||||
|
||||
log_handler = logger.add(self.__log_path, level="DEBUG")
|
||||
self.__start_at = time.time()
|
||||
try:
|
||||
# run step in sequential order
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from httprunner import loader
|
||||
from httprunner.cli import main_run
|
||||
from httprunner.runner import HttpRunner
|
||||
|
||||
|
||||
class TestHttpRunner(unittest.TestCase):
|
||||
def setUp(self):
|
||||
loader.project_meta = None
|
||||
self.runner = HttpRunner()
|
||||
|
||||
def test_run_testcase_by_path_request_only(self):
|
||||
self.runner.run_path(
|
||||
"examples/postman_echo/request_methods/request_with_functions.yml"
|
||||
)
|
||||
result = self.runner.get_summary()
|
||||
self.assertTrue(result.success)
|
||||
self.assertEqual(result.name, "request methods testcase with functions")
|
||||
self.assertEqual(result.step_datas[0].name, "get with params")
|
||||
self.assertEqual(len(result.step_datas), 3)
|
||||
|
||||
def test_run_testcase_by_path_ref_testcase(self):
|
||||
self.runner.run_path(
|
||||
"examples/postman_echo/request_methods/request_with_testcase_reference.yml"
|
||||
)
|
||||
result = self.runner.get_summary()
|
||||
self.assertTrue(result.success)
|
||||
self.assertEqual(result.name, "request methods testcase: reference testcase")
|
||||
self.assertEqual(result.step_datas[0].name, "request with functions")
|
||||
self.assertEqual(len(result.step_datas), 2)
|
||||
|
||||
def test_run_testcase_with_abnormal_path(self):
|
||||
exit_code = main_run(["examples/data/a-b.c/2 3.yml"])
|
||||
self.assertEqual(exit_code, 0)
|
||||
self.assertTrue(os.path.exists("examples/data/a_b_c/__init__.py"))
|
||||
self.assertTrue(os.path.exists("examples/data/debugtalk.py"))
|
||||
self.assertTrue(os.path.exists("examples/data/a_b_c/T1_test.py"))
|
||||
self.assertTrue(os.path.exists("examples/data/a_b_c/T2_3_test.py"))
|
||||
16
httprunner/step_request_test.py
Normal file
16
httprunner/step_request_test.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import unittest
|
||||
|
||||
from examples.postman_echo.request_methods.request_with_functions_test import TestCaseRequestWithFunctions
|
||||
|
||||
|
||||
class TestRunRequest(unittest.TestCase):
|
||||
|
||||
def test_run_request(self):
|
||||
runner = TestCaseRequestWithFunctions().test_start()
|
||||
summary = runner.get_summary()
|
||||
self.assertTrue(summary.success)
|
||||
self.assertEqual(summary.name, "request methods testcase with functions")
|
||||
self.assertEqual(len(summary.step_datas), 3)
|
||||
self.assertEqual(summary.step_datas[0].name, "get with params")
|
||||
self.assertEqual(summary.step_datas[1].name, "post raw text")
|
||||
self.assertEqual(summary.step_datas[2].name, "post form data")
|
||||
@@ -1,16 +1,11 @@
|
||||
import os
|
||||
from typing import Text, Callable
|
||||
from typing import Callable, Text
|
||||
|
||||
from loguru import logger
|
||||
from httprunner import exceptions
|
||||
from httprunner.loader import load_testcase_file
|
||||
|
||||
from httprunner.step_request import call_hooks
|
||||
from httprunner import exceptions
|
||||
from httprunner.models import IStep, StepData, TStep
|
||||
from httprunner.runner import HttpRunner
|
||||
from httprunner.models import (
|
||||
TStep,
|
||||
StepData
|
||||
)
|
||||
from httprunner.step_request import call_hooks
|
||||
|
||||
|
||||
def run_step_testcase(runner: HttpRunner, step: TStep) -> StepData:
|
||||
@@ -25,9 +20,8 @@ def run_step_testcase(runner: HttpRunner, step: TStep) -> StepData:
|
||||
|
||||
# TODO: override testcase with current step name/variables/export
|
||||
|
||||
ref_case_runner = HttpRunner()
|
||||
ref_case_runner.config = step.testcase.config
|
||||
ref_case_runner.teststeps = step.testcase.teststeps
|
||||
# step.testcase is a referenced testcase, e.g. RequestWithFunctions
|
||||
ref_case_runner = step.testcase()
|
||||
ref_case_runner.with_session(runner.session) \
|
||||
.with_case_id(runner.case_id) \
|
||||
.with_variables(step_variables) \
|
||||
@@ -49,7 +43,7 @@ def run_step_testcase(runner: HttpRunner, step: TStep) -> StepData:
|
||||
return step_data
|
||||
|
||||
|
||||
class StepRefCase(object):
|
||||
class StepRefCase(IStep):
|
||||
def __init__(self, step: TStep):
|
||||
self.__step = step
|
||||
|
||||
@@ -95,13 +89,9 @@ class RunTestCase(object):
|
||||
return self
|
||||
|
||||
def call(self, testcase: Callable) -> StepRefCase:
|
||||
if hasattr(testcase, "config") and hasattr(testcase, "teststeps"):
|
||||
if issubclass(testcase, HttpRunner):
|
||||
# referenced testcase object
|
||||
self.__step.testcase = testcase
|
||||
elif isinstance(testcase, Text):
|
||||
if not os.path.isfile(testcase):
|
||||
raise exceptions.ParamsError(f"Invalid testcase path: {testcase}")
|
||||
|
||||
self.__step.testcase = load_testcase_file(testcase)
|
||||
else:
|
||||
raise exceptions.ParamsError(
|
||||
f"Invalid teststep referenced testcase: {testcase}"
|
||||
|
||||
23
httprunner/step_testcase_test.py
Normal file
23
httprunner/step_testcase_test.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import unittest
|
||||
|
||||
from httprunner.runner import HttpRunner
|
||||
from httprunner.step_testcase import RunTestCase
|
||||
from examples.postman_echo.request_methods.request_with_functions_test import TestCaseRequestWithFunctions
|
||||
|
||||
|
||||
class TestRunTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.runner = HttpRunner()
|
||||
|
||||
def test_run_testcase_by_path(self):
|
||||
|
||||
step_data = RunTestCase("run referenced testcase").call(
|
||||
TestCaseRequestWithFunctions
|
||||
).run(self.runner)
|
||||
self.assertTrue(step_data.success)
|
||||
self.assertEqual(step_data.name, "run referenced testcase")
|
||||
self.assertEqual(len(step_data.data), 3)
|
||||
self.assertEqual(step_data.data[0].name, "get with params")
|
||||
self.assertEqual(step_data.data[1].name, "post raw text")
|
||||
self.assertEqual(step_data.data[2].name, "post form data")
|
||||
Reference in New Issue
Block a user