Merge pull request #3 from billduan/feat_decoupling

fix: codeview
This commit is contained in:
billduan
2022-05-07 11:39:54 +08:00
committed by GitHub
9 changed files with 169 additions and 111 deletions

View File

@@ -1,17 +1,22 @@
__version__ = "v4.0.0"
__description__ = "One-stop solution for HTTP(S) testing."
from httprunner.config import Config
import platform
from httprunner.parser import parse_parameters as Parameters
from httprunner.runner import HttpRunner
from httprunner.step import Step
from httprunner.step_request import RunRequest
from httprunner.step_testcase import RunTestCase
from httprunner.step_sql_request import (
RunSqlRequest,
StepSqlRequestValidation,
StepSqlRequestExtraction,
StepSqlRequestValidation,
)
from httprunner.step_testcase import RunTestCase
from httprunner.step_thrift_request import (
RunThriftRequest,
StepThriftRequestExtraction,
StepThriftRequestValidation,
)
__all__ = [
@@ -26,18 +31,7 @@ __all__ = [
"StepSqlRequestExtraction",
"RunTestCase",
"Parameters",
"RunThriftRequest",
"StepThriftRequestValidation",
"StepThriftRequestExtraction",
]
if platform.system() != "Windows":
from httprunner.step_thrift_request import (
RunThriftRequest,
StepThriftRequestValidation,
StepThriftRequestExtraction,
)
__all__.extend(
[
"RunThriftRequest",
"StepThriftRequestValidation",
"StepThriftRequestExtraction",
]
)

View File

@@ -29,17 +29,17 @@ class MethodEnum(Text, Enum):
class ProtoType(Enum):
pBinary = 1
pCyBinary = 2
pCompact = 3
pJson = 4
Binary = 1
CyBinary = 2
Compact = 3
Json = 4
class TransType(Enum):
tBuffered = 1
tCyBuffered = 2
tFramed = 3
tCyFramed = 4
Buffered = 1
CyBuffered = 2
Framed = 3
CyFramed = 4
# configs for thrift rpc
@@ -56,8 +56,8 @@ class TConfigThrift(BaseModel):
ip: Text = "127.0.0.1"
port: int = 9000
service_name: Text = None
proto_type: ProtoType = ProtoType.pBinary
trans_type: TransType = TransType.tBuffered
proto_type: ProtoType = ProtoType.Binary
trans_type: TransType = TransType.Buffered
# configs for db

View File

@@ -91,9 +91,11 @@ class SessionRunner(object):
def with_thrift_client(self, thrift_client) -> "SessionRunner":
self.thrift_client = thrift_client
return self
def with_db_engine(self, db_engine):
def with_db_engine(self, db_engine) -> "SessionRunner":
self.db_engine = db_engine
return self
def __parse_config(self, param: Dict = None) -> None:
# parse config variables

View File

@@ -1,18 +1,22 @@
import platform
from typing import Union
from httprunner import HttpRunner
from httprunner.models import StepResult, TRequest, TStep, TestCase
from httprunner.runner import HttpRunner
from httprunner.step_request import (
RequestWithOptionalArgs,
StepRequestExtraction,
StepRequestValidation,
)
from httprunner.step_testcase import StepRefCase
from httprunner.step_sql_request import (
RunSqlRequest,
StepSqlRequestValidation,
StepSqlRequestExtraction,
StepSqlRequestValidation,
)
from httprunner.step_testcase import StepRefCase
from httprunner.step_thrift_request import (
RunThriftRequest,
StepThriftRequestExtraction,
StepThriftRequestValidation,
)
@@ -27,6 +31,9 @@ class Step(object):
RunSqlRequest,
StepSqlRequestValidation,
StepSqlRequestExtraction,
RunThriftRequest,
StepThriftRequestValidation,
StepThriftRequestExtraction,
],
):
self.__step = step
@@ -57,30 +64,4 @@ class Step(object):
return self.__step.type()
def run(self, runner: HttpRunner) -> StepResult:
return self.__step.run(runner)
if platform.system() != "Windows":
from httprunner.step_thrift_request import (
RunThriftRequest,
StepThriftRequestValidation,
StepThriftRequestExtraction,
)
class Step(Step):
def __init__(
self,
step: Union[
StepRequestValidation,
StepRequestExtraction,
RequestWithOptionalArgs,
StepRefCase,
RunSqlRequest,
StepSqlRequestValidation,
StepSqlRequestExtraction,
RunThriftRequest,
StepThriftRequestValidation,
StepThriftRequestExtraction,
],
):
super().__init__(step)
return self.__step.run(runner)

View File

@@ -1,22 +1,41 @@
# -*- coding: utf-8 -*-
import sys
import time
from typing import Text
from loguru import logger
from httprunner import utils
from httprunner.exceptions import SqlMethodNotSupport
from httprunner.exceptions import ValidationFailure
from httprunner.models import IStep, StepResult, TStep
from httprunner.models import TSqlRequest, SqlMethodEnum
from httprunner.models import SqlMethodEnum, TSqlRequest
from httprunner.response import SqlResponseObject
from httprunner.runner import HttpRunner
from httprunner.step_request import (
call_hooks,
StepRequestExtraction,
StepRequestValidation,
)
from httprunner.database.engine import DBEngine
from httprunner.exceptions import SqlMethodNotSupport
from httprunner.step_request import (StepRequestExtraction, StepRequestValidation, call_hooks)
try:
import sqlalchemy
import pymysql
SQL_READY = True
except ModuleNotFoundError:
SQL_READY = False
def ensure_sql_ready():
if SQL_READY:
return
msg = """
uploader extension dependencies uninstalled, install first and try again.
install with pip:
$ pip install sqlalchemy pymysql
or you can install httprunner with optional upload dependencies:
$ pip install "httprunner[sql]"
"""
logger.error(msg)
sys.exit(1)
def run_step_sql_request(runner: HttpRunner, step: TStep) -> StepResult:
@@ -52,6 +71,8 @@ def run_step_sql_request(runner: HttpRunner, step: TStep) -> StepResult:
)
if not runner.db_engine:
ensure_sql_ready()
from httprunner.database.engine import DBEngine
runner.db_engine = DBEngine(
f'mysql+pymysql://{parsed_request_dict["db_config"]["user"]}:'
f'{parsed_request_dict["db_config"]["password"]}@{parsed_request_dict["db_config"]["ip"]}:'

View File

@@ -1,21 +1,53 @@
# -*- coding: utf-8 -*-
import platform
import sys
import time
from typing import Text, Union
from loguru import logger
from httprunner import utils
from httprunner.exceptions import ValidationFailure
from httprunner.models import IStep, StepResult, TStep, ProtoType, TransType
from httprunner.models import (
IStep,
ProtoType,
StepResult,
TStep,
TThriftRequest,
TransType,
)
from httprunner.response import ThriftResponseObject
from httprunner.runner import HttpRunner
from httprunner.step_request import (
call_hooks,
StepRequestExtraction,
StepRequestValidation,
call_hooks,
)
from httprunner.models import TThriftRequest
from httprunner.response import ThriftResponseObject
from httprunner.thrift.thrift_client import ThriftClient
try:
import thriftpy2
from thrift.Thrift import TType
THRIFT_READY = True
except ModuleNotFoundError:
THRIFT_READY = False
def ensure_thrift_ready():
assert platform.system() != "Windows", "Sorry,thrift not support Windows for now"
if THRIFT_READY:
return
msg = """
uploader extension dependencies uninstalled, install first and try again.
install with pip:
$ pip install cython thriftpy2 thrift
or you can install httprunner with optional upload dependencies:
$ pip install "httprunner[thrift]"
"""
logger.error(msg)
sys.exit(1)
def run_step_thrift_request(runner: HttpRunner, step: TStep) -> StepResult:
@@ -34,30 +66,30 @@ def run_step_thrift_request(runner: HttpRunner, step: TStep) -> StepResult:
parsed_request_dict["psm"] = parsed_request_dict["psm"] or config.thrift.psm
parsed_request_dict["env"] = parsed_request_dict["env"] or config.thrift.env
parsed_request_dict["cluster"] = (
parsed_request_dict["cluster"] or config.thrift.cluster
parsed_request_dict["cluster"] or config.thrift.cluster
)
parsed_request_dict["idl_path"] = (
parsed_request_dict["idl_path"] or config.thrift.idl_path
parsed_request_dict["idl_path"] or config.thrift.idl_path
)
parsed_request_dict["include_dirs"] = (
parsed_request_dict["include_dirs"] or config.thrift.include_dirs
parsed_request_dict["include_dirs"] or config.thrift.include_dirs
)
parsed_request_dict["method"] = (
parsed_request_dict["method"] or config.thrift.method
parsed_request_dict["method"] or config.thrift.method
)
parsed_request_dict["service_name"] = (
parsed_request_dict["service_name"] or config.thrift.service_name
parsed_request_dict["service_name"] or config.thrift.service_name
)
parsed_request_dict["ip"] = parsed_request_dict["ip"] or config.thrift.ip
parsed_request_dict["port"] = parsed_request_dict["port"] or config.thrift.port
parsed_request_dict["proto_type"] = (
parsed_request_dict["proto_type"] or config.thrift.proto_type
parsed_request_dict["proto_type"] or config.thrift.proto_type
)
parsed_request_dict["trans_port"] = (
parsed_request_dict["trans_type"] or config.thrift.trans_type
parsed_request_dict["trans_type"] or config.thrift.trans_type
)
parsed_request_dict["timeout"] = (
parsed_request_dict["timeout"] or config.thrift.timeout
parsed_request_dict["timeout"] or config.thrift.timeout
)
parsed_request_dict["thrift_client"] = parsed_request_dict["thrift_client"]
@@ -71,6 +103,8 @@ def run_step_thrift_request(runner: HttpRunner, step: TStep) -> StepResult:
if not runner.thrift_client:
runner.thrift_client = parsed_request_dict["thrift_client"]
if not runner.thrift_client:
ensure_thrift_ready()
from httprunner.thrift.thrift_client import ThriftClient
runner.thrift_client = ThriftClient(
thrift_file=parsed_request_dict["idl_path"],
service_name=parsed_request_dict["service_name"],
@@ -180,7 +214,7 @@ class RunThriftRequest(IStep):
return self
def teardown_hook(
self, hook: Text, assign_var_name: Text = None
self, hook: Text, assign_var_name: Text = None
) -> "RunThriftRequest":
if assign_var_name:
self.__step.teardown_hooks.append({assign_var_name: hook})
@@ -190,7 +224,7 @@ class RunThriftRequest(IStep):
return self
def setup_hook(
self, hook: Text, assign_var_name: Text = None
self, hook: Text, assign_var_name: Text = None
) -> "RunThriftRequest":
if assign_var_name:
self.__step.setup_hooks.append({assign_var_name: hook})
@@ -213,7 +247,7 @@ class RunThriftRequest(IStep):
return self
def with_thrift_client(
self, thrift_client: Union["ThriftClient", str]
self, thrift_client: Union["ThriftClient", str]
) -> "RunThriftRequest":
self.__step.thrift_request.thrift_client = thrift_client
return self
@@ -253,7 +287,7 @@ class RunThriftRequest(IStep):
return StepThriftRequestValidation(self.__step)
def with_jmespath(
self, jmes_path: Text, var_name: Text
self, jmes_path: Text, var_name: Text
) -> "StepThriftRequestExtraction":
self.__step.extract[var_name] = jmes_path
return StepThriftRequestExtraction(self.__step)

View File

@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import enum
import json
from loguru import logger
import thriftpy2
from loguru import logger
from thriftpy2.protocol import (
TBinaryProtocolFactory,
TCompactProtocolFactory,
@@ -18,23 +19,22 @@ from thriftpy2.transport import (
TCyFramedTransportFactory,
TFramedTransportFactory,
)
from thriftpy2.utils import deserialize
from httprunner.thrift.data_convertor import json2thrift, thrift2json, thrift2dict
from httprunner.thrift.data_convertor import json2thrift, thrift2dict
class ProtoType(enum.Enum):
pBinary = 1
pCyBinary = 2
pCompact = 3
pJson = 4
Binary = 1
CyBinary = 2
Compact = 3
Json = 4
class TransType(enum.Enum):
tBuffered = 1
tCyBuffered = 2
tFramed = 3
tCyFramed = 4
Buffered = 1
CyBuffered = 2
Framed = 3
CyFramed = 4
class RequestFormat(enum.Enum):
@@ -43,24 +43,24 @@ class RequestFormat(enum.Enum):
def get_proto_factory(proto_type):
if proto_type == ProtoType.pBinary:
if proto_type == ProtoType.Binary:
return TBinaryProtocolFactory()
if proto_type == ProtoType.pCyBinary:
if proto_type == ProtoType.CyBinary:
return TCyBinaryProtocolFactory()
if proto_type == ProtoType.pCompact:
if proto_type == ProtoType.Compact:
return TCompactProtocolFactory()
if proto_type == ProtoType.pJson:
if proto_type == ProtoType.Json:
return TJSONProtocolFactory()
def get_trans_factory(trans_type):
if trans_type == TransType.tBuffered:
if trans_type == TransType.Buffered:
return TBufferedTransportFactory()
if trans_type == TransType.tCyBuffered:
if trans_type == TransType.CyBuffered:
return TCyBufferedTransportFactory()
if trans_type == TransType.tFramed:
if trans_type == TransType.Framed:
return TFramedTransportFactory()
if trans_type == TransType.tCyFramed:
if trans_type == TransType.CyFramed:
return TCyFramedTransportFactory()
@@ -73,8 +73,8 @@ class ThriftClient(object):
port,
include_dirs=None,
timeout=3000,
proto_type=ProtoType.pCyBinary,
trans_type=TransType.tCyBuffered,
proto_type=ProtoType.CyBinary,
trans_type=TransType.CyBuffered,
):
self.thrift_file = thrift_file
self.include_dirs = include_dirs

25
poetry.lock generated
View File

@@ -459,6 +459,23 @@ type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "tsinghua"
[[package]]
name = "pymysql"
version = "1.0.2"
description = "Pure Python MySQL Driver"
category = "main"
optional = true
python-versions = ">=3.6"
[package.extras]
ed25519 = ["PyNaCl (>=1.4.0)"]
rsa = ["cryptography"]
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "tsinghua"
[[package]]
name = "pyparsing"
version = "3.0.7"
@@ -815,12 +832,14 @@ reference = "tsinghua"
[extras]
allure = ["allure-pytest"]
sql = ["sqlalchemy", "pymysql"]
thrift = ["cython", "thrift", "thriftpy2"]
upload = ["requests-toolbelt", "filetype"]
[metadata]
lock-version = "1.1"
python-versions = "^3.7"
content-hash = "15f15916b41e180ee7567716713607183f5d8c8d30300c24dada98be454bc675"
content-hash = "a00de4a66e9c8b73709f339d266be673ca6057dfd4023504677054697611986d"
[metadata.files]
allure-pytest = [
@@ -1195,6 +1214,10 @@ pydantic = [
{file = "pydantic-1.8.2-py3-none-any.whl", hash = "sha256:fec866a0b59f372b7e776f2d7308511784dace622e0992a0b59ea3ccee0ae833"},
{file = "pydantic-1.8.2.tar.gz", hash = "sha256:26464e57ccaafe72b7ad156fdaa4e9b9ef051f69e175dbbb463283000c05ab7b"},
]
pymysql = [
{file = "PyMySQL-1.0.2-py3-none-any.whl", hash = "sha256:41fc3a0c5013d5f039639442321185532e3e2c8924687abe6537de157d403641"},
{file = "PyMySQL-1.0.2.tar.gz", hash = "sha256:816927a350f38d56072aeca5dfb10221fe1dc653745853d30a216637f5d7ad36"},
]
pyparsing = [
{file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"},
{file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"},

View File

@@ -45,14 +45,17 @@ filetype = {version = "^1.0.7", optional = true}
Brotli = "^1.0.9"
jinja2 = "^3.0.3"
toml = "^0.10.2"
sqlalchemy = "^1.4.36"
cython = "^0.29.28"
thriftpy2 = "^0.4.14"
thrift = "^0.16.0"
sqlalchemy = {version = "^1.4.36", optional = true}
pymysql = {version = "^1.0.2",optional = true}
cython = {version = "^0.29.28", optional = true}
thriftpy2 = {version = "^0.4.14", optional = true}
thrift = {version = "^0.16.0", optional = true}
[tool.poetry.extras]
allure = ["allure-pytest"] # pip install "httprunner[allure]", poetry install -E allure
upload = ["requests-toolbelt", "filetype"] # pip install "httprunner[upload]", poetry install -E upload
sql = ["sqlalchemy","pymysql"] # pip install "httprunner[sql]", poetry install -E sql
thrift = ["cython","thrift","thriftpy2"] # pip install "httprunner[thrift]", poetry install -E sql
[tool.poetry.dev-dependencies]
coverage = "^4.5.4"