From e7aca434700d7572ac58f012ca9d01a52ad379c4 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Mon, 1 Jun 2020 11:25:16 +0800 Subject: [PATCH] feat: describe testcase in chain-call style --- .../request_with_functions_test.py | 141 ++++++++---------- httprunner/__init__.py | 7 +- httprunner/runner.py | 116 ++++++++++++++ httprunner/schema.py | 4 +- pyproject.toml | 2 +- 5 files changed, 189 insertions(+), 81 deletions(-) diff --git a/examples/postman_echo/request_methods/request_with_functions_test.py b/examples/postman_echo/request_methods/request_with_functions_test.py index b8f333bb..78a4ac4f 100644 --- a/examples/postman_echo/request_methods/request_with_functions_test.py +++ b/examples/postman_echo/request_methods/request_with_functions_test.py @@ -1,88 +1,77 @@ # NOTICE: Generated By HttpRunner. DO NOT EDIT! # FROM: examples/postman_echo/request_methods/request_with_functions.yml -from httprunner import HttpRunner, TConfig, TStep +from httprunner import HttpRunner, Config, Step, Request class TestCaseRequestWithFunctions(HttpRunner): - config = TConfig( - **{ - "name": "request methods testcase with functions", - "variables": {"foo1": "session_bar1"}, - "base_url": "https://postman-echo.com", - "verify": False, - "path": "examples/postman_echo/request_methods/request_with_functions_test.py", - } + config = ( + Config("request methods testcase with functions") + .set_variables(foo1="session_bar1") + .set_base_url("https://postman-echo.com") + .set_verify(False) + .set_path( + "examples/postman_echo/request_methods/request_with_functions_test.py" + ) + .init() ) teststeps = [ - TStep( - **{ - "name": "get with params", - "variables": { - "foo1": "bar1", - "foo2": "session_bar2", - "sum_v": "${sum_two(1, 2)}", - }, - "request": { - "method": "GET", - "url": "/get", - "params": {"foo1": "$foo1", "foo2": "$foo2", "sum_v": "$sum_v"}, - "headers": {"User-Agent": "HttpRunner/${get_httprunner_version()}"}, - }, - "extract": {"session_foo2": "body.args.foo2"}, - "validate": [ - {"eq": ["status_code", 200]}, - {"eq": ["body.args.foo1", "session_bar1"]}, - {"eq": ["body.args.sum_v", "3"]}, - {"eq": ["body.args.foo2", "session_bar2"]}, - ], - } - ), - TStep( - **{ - "name": "post raw text", - "variables": {"foo1": "hello world", "foo3": "$session_foo2"}, - "request": { - "method": "POST", - "url": "/post", - "headers": { - "User-Agent": "HttpRunner/${get_httprunner_version()}", - "Content-Type": "text/plain", - }, - "data": "This is expected to be sent back as part of response body: $foo1-$foo3.", - }, - "validate": [ - {"eq": ["status_code", 200]}, - { - "eq": [ - "body.data", - "This is expected to be sent back as part of response body: session_bar1-session_bar2.", - ] - }, - ], - } - ), - TStep( - **{ - "name": "post form data", - "variables": {"foo1": "bar1", "foo2": "bar2"}, - "request": { - "method": "POST", - "url": "/post", - "headers": { - "User-Agent": "HttpRunner/${get_httprunner_version()}", - "Content-Type": "application/x-www-form-urlencoded", - }, - "data": "foo1=$foo1&foo2=$foo2", - }, - "validate": [ - {"eq": ["status_code", 200]}, - {"eq": ["body.form.foo1", "session_bar1"]}, - {"eq": ["body.form.foo2", "bar2"]}, - ], - } - ), + Step("get with params") + .set_variables(foo1="bar1", foo2="session_bar2", sum_v="${sum_two(1, 2)}") + .run_request( + Request() + .set_method("GET") + .set_url("/get") + .set_params(foo1="$foo1", foo2="$foo2", sum_v="$sum_v") + .set_headers(**{"User-Agent": "HttpRunner/${get_httprunner_version()}"}) + ) + .extract("session_foo2", "body.args.foo2") + .assert_equal("status_code", 200) + .assert_equal("body.args.foo1", "session_bar1") + .assert_equal("body.args.sum_v", "3") + .assert_equal("body.args.foo2", "session_bar2") + .init(), + Step("post raw text") + .set_variables(foo1="hello world", foo3="$session_foo2") + .run_request( + Request() + .set_method("POST") + .set_url("/post") + .set_headers( + **{ + "User-Agent": "HttpRunner/${get_httprunner_version()}", + "Content-Type": "text/plain", + } + ) + .set_data( + "This is expected to be sent back as part of response body: $foo1-$foo3." + ) + ) + .assert_equal("status_code", 200) + .assert_equal( + "body.data", + "This is expected to be sent back as part of response body: session_bar1-session_bar2.", + ) + .init(), + Step("post form data") + .set_variables(**{"foo1": "bar1", "foo2": "bar2"}) + .run_request( + Request() + .set_method("POST") + .set_url("/post") + .set_headers( + **{ + "User-Agent": "HttpRunner/${get_httprunner_version()}", + "Content-Type": "application/x-www-form-urlencoded", + } + ) + .set_data("foo1=$foo1&foo2=$foo2") + ) + .assert_equal("status_code", 200) + .assert_equal("body.form.foo1", "session_bar1") + .assert_equal("body.form.foo2", "bar2") + .init(), ] diff --git a/httprunner/__init__.py b/httprunner/__init__.py index d6cc44a1..2c1e9ef4 100644 --- a/httprunner/__init__.py +++ b/httprunner/__init__.py @@ -1,7 +1,7 @@ -__version__ = "3.0.6" +__version__ = "3.0.7" __description__ = "One-stop solution for HTTP(S) testing." -from httprunner.runner import HttpRunner +from httprunner.runner import HttpRunner, Config, Step, Request from httprunner.schema import TConfig, TStep __all__ = [ @@ -10,4 +10,7 @@ __all__ = [ "HttpRunner", "TConfig", "TStep", + "Config", + "Step", + "Request", ] diff --git a/httprunner/runner.py b/httprunner/runner.py index d236d471..a658e561 100644 --- a/httprunner/runner.py +++ b/httprunner/runner.py @@ -30,9 +30,125 @@ from httprunner.schema import ( TestCaseInOut, ProjectMeta, TestCase, + TRequest, ) +class Config(object): + def __init__(self, name): + self.__name = name + self.__variables = {} + self.__base_url = "" + self.__verify = False + self.__path = "" + + def set_variables(self, **variables): + self.__variables.update(variables) + return self + + def set_base_url(self, base_url): + self.__base_url = base_url + return self + + def set_verify(self, verify): + self.__verify = verify + return self + + def set_path(self, path): + self.__path = path + return self + + def init(self): + return TConfig( + name=self.__name, + base_url=self.__base_url, + verify=self.__verify, + variables=self.__variables, + path=self.__path, + ) + + +class Request(object): + def __init__(self): + self.__method = "GET" + self.__url = "" + self.__params = {} + self.__headers = {} + self.__data = "" + + def set_method(self, method): + self.__method = method + return self + + def set_url(self, url): + self.__url = url + return self + + def set_params(self, **params): + self.__params.update(params) + return self + + def set_headers(self, **headers): + self.__headers.update(headers) + return self + + def set_data(self, data): + self.__data = data + return self + + def perform(self): + """build TRequest object with configs""" + return TRequest( + method=self.__method, + url=self.__url, + params=self.__params, + headers=self.__headers, + data=self.__data, + ) + + +class Step(object): + def __init__(self, name): + self.__name = name + self.__variables = {} + self.__request = None + self.__extract = {} + self.__validators = [] + + def set_variables(self, **variables): + self.__variables.update(variables) + return self + + def extract(self, var_name, jmes_path): + self.__extract[var_name] = jmes_path + return self + + def assert_equal(self, jmes_path, expected_value): + self.__validators.append({"eq": [jmes_path, expected_value]}) + return self + + def assert_greater_than(self, jmes_path, expected_value): + self.__validators.append({"gt": [jmes_path, expected_value]}) + return self + + def assert_less_than(self, jmes_path, expected_value): + self.__validators.append({"lt": [jmes_path, expected_value]}) + return self + + def run_request(self, req_obj: Request) -> "Step": + self.__request = req_obj.perform() + return self + + def init(self): + return TStep( + name=self.__name, + variables=self.__variables, + request=self.__request, + extract=self.__extract, + validate=self.__validators, + ) + + class HttpRunner(object): config: TConfig teststeps: List[TStep] diff --git a/httprunner/schema.py b/httprunner/schema.py index 986f6cb2..217d294d 100644 --- a/httprunner/schema.py +++ b/httprunner/schema.py @@ -45,7 +45,7 @@ class TConfig(BaseModel): path: Text = None -class Request(BaseModel): +class TRequest(BaseModel): """requests.Request model""" method: MethodEnum = MethodEnum.GET @@ -63,7 +63,7 @@ class Request(BaseModel): class TStep(BaseModel): name: Name - request: Request = None + request: TRequest = None testcase: Union[Text, Callable] = "" variables: VariablesMapping = {} setup_hooks: Hook = [] diff --git a/pyproject.toml b/pyproject.toml index ec8c3459..083c1725 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "httprunner" -version = "3.0.6" +version = "3.0.7" description = "One-stop solution for HTTP(S) testing." license = "Apache-2.0" readme = "README.md"