mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-11 18:11:21 +08:00
change v3: add basic extract
This commit is contained in:
@@ -23,6 +23,9 @@ class TestCaseRequestMethodsHardcode(TestCaseRunner):
|
||||
"User-Agent": "HttpRunner/3.0"
|
||||
}
|
||||
},
|
||||
"extract": {
|
||||
"server": "headers.Server"
|
||||
},
|
||||
"validate": [
|
||||
{"eq": ["status_code", 200]},
|
||||
{"eq": ["headers.Server", "nginx"]}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
from typing import Dict, Text, Any
|
||||
|
||||
import jmespath
|
||||
import requests
|
||||
from loguru import logger
|
||||
|
||||
from httprunner.v3.exceptions import ParamsError, ValidationFailure
|
||||
from httprunner.v3.validator import uniform_validator, AssertMethods
|
||||
|
||||
|
||||
class ResponseObject(object):
|
||||
@@ -10,4 +17,45 @@ class ResponseObject(object):
|
||||
resp_obj (instance): requests.Response instance
|
||||
|
||||
"""
|
||||
self.obj = resp_obj
|
||||
self.resp_obj_meta = {
|
||||
"status_code": resp_obj.status_code,
|
||||
"headers": resp_obj.headers,
|
||||
"body": resp_obj.json()
|
||||
}
|
||||
|
||||
def validate(self, validators):
|
||||
|
||||
for v in validators:
|
||||
u_validator = uniform_validator(v)
|
||||
field = u_validator["check"]
|
||||
assert_method = u_validator["assert"]
|
||||
expect_value = u_validator["expect"]
|
||||
actual_value = jmespath.search(field, self.resp_obj_meta)
|
||||
|
||||
msg = f"assert {field} {assert_method} {expect_value}"
|
||||
|
||||
try:
|
||||
assert_func = getattr(AssertMethods, assert_method)
|
||||
except AttributeError:
|
||||
raise ParamsError(f"Assert Method not supported: {assert_method}")
|
||||
|
||||
try:
|
||||
assert_func(actual_value, expect_value)
|
||||
msg += " - success"
|
||||
logger.info(msg)
|
||||
except AssertionError:
|
||||
msg += " - fail"
|
||||
logger.error(msg)
|
||||
raise ValidationFailure(f"assert {field}: {actual_value} {assert_method} {expect_value}")
|
||||
|
||||
def extract(self, extractors: Dict[Text, Text]) -> Dict[Text, Any]:
|
||||
if not extractors:
|
||||
return {}
|
||||
|
||||
extract_mapping = {}
|
||||
for key, field in extractors.items():
|
||||
field_value = jmespath.search(field, self.resp_obj_meta)
|
||||
extract_mapping[key] = field_value
|
||||
|
||||
logger.info(f"extract mapping: {extract_mapping}")
|
||||
return extract_mapping
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from httprunner.v3.parser import build_url
|
||||
from httprunner.v3.schema import TestsConfig, TestStep
|
||||
from httprunner.v3.validator import Validator
|
||||
from httprunner.v3.response import ResponseObject
|
||||
from httprunner.v3.schema import TestsConfig, TestStep
|
||||
|
||||
|
||||
class TestCaseRunner(object):
|
||||
@@ -41,18 +39,25 @@ class TestCaseRunner(object):
|
||||
# request
|
||||
session = self.session or requests.Session()
|
||||
resp = session.request(method, url, **request_dict)
|
||||
resp_obj = ResponseObject(resp)
|
||||
|
||||
# validate
|
||||
resp_obj = ResponseObject(resp)
|
||||
validator = Validator(resp_obj)
|
||||
validators = step.validation
|
||||
validator.validate(validators)
|
||||
resp_obj.validate(validators)
|
||||
|
||||
# extract
|
||||
extractors = step.extract
|
||||
extract_mapping = resp_obj.extract(extractors)
|
||||
return extract_mapping
|
||||
|
||||
def test_start(self):
|
||||
"""main entrance"""
|
||||
session_variables = {}
|
||||
for step in self.teststeps:
|
||||
step.variables.update(self.config.variables)
|
||||
self.run_step(step)
|
||||
step.variables.update(session_variables)
|
||||
extract_mapping = self.run_step(step)
|
||||
session_variables.update(extract_mapping)
|
||||
|
||||
def run(self):
|
||||
"""main entrance alias for test_start"""
|
||||
|
||||
@@ -56,5 +56,5 @@ class TestStep(BaseModel):
|
||||
name: Name
|
||||
request: Request
|
||||
variables: Variables = {}
|
||||
extract: Union[Dict[Text, Text], List[Text]] = {}
|
||||
extract: Dict[Text, Text] = {}
|
||||
validation: Validate = Field([], alias="validate")
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
from typing import Text
|
||||
|
||||
import jmespath
|
||||
from loguru import logger
|
||||
|
||||
from httprunner.v3.exceptions import ParamsError, ValidationFailure
|
||||
from httprunner.v3.response import ResponseObject
|
||||
from httprunner.v3.exceptions import ParamsError
|
||||
|
||||
|
||||
def get_uniform_comparator(comparator: Text):
|
||||
@@ -108,38 +104,3 @@ class AssertMethods(object):
|
||||
@staticmethod
|
||||
def greater_than(actual_value, expect_value):
|
||||
assert actual_value > expect_value
|
||||
|
||||
|
||||
class Validator(object):
|
||||
|
||||
def __init__(self, resp_obj: ResponseObject):
|
||||
self.resp_meta = {
|
||||
"status_code": resp_obj.obj.status_code,
|
||||
"headers": resp_obj.obj.headers,
|
||||
"body": resp_obj.obj.json()
|
||||
}
|
||||
|
||||
def validate(self, validators):
|
||||
|
||||
for v in validators:
|
||||
u_validator = uniform_validator(v)
|
||||
field = u_validator["check"]
|
||||
assert_method = u_validator["assert"]
|
||||
expect_value = u_validator["expect"]
|
||||
actual_value = jmespath.search(field, self.resp_meta)
|
||||
|
||||
msg = f"assert {field} {assert_method} {expect_value}"
|
||||
|
||||
try:
|
||||
assert_func = getattr(AssertMethods, assert_method)
|
||||
except AttributeError:
|
||||
raise ParamsError(f"Assert Method not supported: {assert_method}")
|
||||
|
||||
try:
|
||||
assert_func(actual_value, expect_value)
|
||||
msg += " - success"
|
||||
logger.info(msg)
|
||||
except AssertionError:
|
||||
msg += " - fail"
|
||||
logger.error(msg)
|
||||
raise ValidationFailure(f"assert {field}: {actual_value} {assert_method} {expect_value}")
|
||||
|
||||
Reference in New Issue
Block a user