From af1a45219089db04eb9fa3e8724adbf4573fc67b Mon Sep 17 00:00:00 2001 From: debugtalk Date: Mon, 20 Apr 2020 12:03:08 +0800 Subject: [PATCH] v3 feat: support teststep variables --- .../request_methods/with_functions.yml | 0 .../request_methods/with_variables.yml | 53 ++++++++++++ .../request_methods/with_variables_test.py | 80 +++++++++++++++++++ httprunner/v3/parser.py | 4 +- httprunner/v3/runner.py | 17 ++-- 5 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 examples/postman_echo/request_methods/with_functions.yml create mode 100644 examples/postman_echo/request_methods/with_variables.yml create mode 100644 examples/postman_echo/request_methods/with_variables_test.py diff --git a/examples/postman_echo/request_methods/with_functions.yml b/examples/postman_echo/request_methods/with_functions.yml new file mode 100644 index 00000000..e69de29b diff --git a/examples/postman_echo/request_methods/with_variables.yml b/examples/postman_echo/request_methods/with_variables.yml new file mode 100644 index 00000000..050d7910 --- /dev/null +++ b/examples/postman_echo/request_methods/with_variables.yml @@ -0,0 +1,53 @@ +config: + name: "request methods testcase with variables" + base_url: "https://postman-echo.com" + verify: False + +teststeps: +- + name: get with params + variables: + foo1: bar1 + foo2: bar2 + request: + method: GET + url: /get + params: + foo1: $foo1 + foo2: $foo2 + headers: + User-Agent: HttpRunner/3.0 + validate: + - eq: ["status_code", 200] + - eq: ["body.args.foo1", "bar1"] + - eq: ["body.args.foo2", "bar2"] +- + name: post raw text + variables: + foo1: "hello world" + request: + method: POST + url: /post + headers: + User-Agent: HttpRunner/3.0 + Content-Type: "text/plain" + data: "This is expected to be sent back as part of response body: $foo1." + validate: + - eq: ["status_code", 200] + - eq: ["body.data", "This is expected to be sent back as part of response body: hello world."] +- + name: post form data + variables: + foo1: bar1 + foo2: bar2 + request: + method: POST + url: /post + headers: + User-Agent: HttpRunner/3.0 + Content-Type: "application/x-www-form-urlencoded" + data: "foo1=$foo1&foo2=$foo2" + validate: + - eq: ["status_code", 200] + - eq: ["body.form.foo1", "bar1"] + - eq: ["body.form.foo2", "bar2"] diff --git a/examples/postman_echo/request_methods/with_variables_test.py b/examples/postman_echo/request_methods/with_variables_test.py new file mode 100644 index 00000000..cdec850e --- /dev/null +++ b/examples/postman_echo/request_methods/with_variables_test.py @@ -0,0 +1,80 @@ +from httprunner.v3.runner import TestCaseRunner +from httprunner.v3.schema import TestsConfig, TestStep + + +class TestCaseRequestMethodsWithVariables(TestCaseRunner): + config = TestsConfig(**{ + "name": "request methods testcase with variables", + "base_url": "https://postman-echo.com", + "verify": False + }) + + teststeps = [ + TestStep(**{ + "name": "get with params", + "variables": { + "foo1": "bar1", + "foo2": "bar2" + }, + "request": { + "method": "GET", + "url": "/get", + "params": { + "foo1": "$foo1", + "foo2": "$foo2" + }, + "headers": { + "User-Agent": "HttpRunner/3.0" + } + }, + "validate": [ + {"eq": ["status_code", 200]}, + {"eq": ["body.args.foo1", "bar1"]}, + {"eq": ["body.args.foo2", "bar2"]} + ] + }), + TestStep(**{ + "name": "post raw text", + "variables": { + "foo1": "hello world" + }, + "request": { + "method": "POST", + "url": "/post", + "data": "This is expected to be sent back as part of response body: $foo1.", + "headers": { + "User-Agent": "HttpRunner/3.0", + "Content-Type": "text/plain" + } + }, + "validate": [ + {"eq": ["status_code", 200]}, + {"eq": ["body.data", "This is expected to be sent back as part of response body: hello world."]}, + ] + }), + TestStep(**{ + "name": "post form data", + "variables": { + "foo1": "bar1", + "foo2": "bar2" + }, + "request": { + "method": "POST", + "url": "/post", + "data": "foo1=$foo1&foo2=$foo2", + "headers": { + "User-Agent": "HttpRunner/3.0", + "Content-Type": "application/x-www-form-urlencoded" + } + }, + "validate": [ + {"eq": ["status_code", 200]}, + {"eq": ["body.form.foo1", "bar1"]}, + {"eq": ["body.form.foo2", "bar2"]} + ] + }) + ] + + +if __name__ == '__main__': + TestCaseRequestMethodsWithVariables().run() diff --git a/httprunner/v3/parser.py b/httprunner/v3/parser.py index c1ed97a9..c3365490 100644 --- a/httprunner/v3/parser.py +++ b/httprunner/v3/parser.py @@ -101,7 +101,7 @@ def parse_string_variables(content, variables_mapping): variable_value = variables_mapping[variable_name] # TODO: replace variable label from $var to {{var}} - if "${}".format(variable_name) == content: + if f"${variable_name}" == content: # content is a variable content = variable_value else: @@ -110,7 +110,7 @@ def parse_string_variables(content, variables_mapping): variable_value = str(variable_value) content = content.replace( - "${}".format(variable_name), + f"${variable_name}", variable_value, 1 ) diff --git a/httprunner/v3/runner.py b/httprunner/v3/runner.py index 49fb6303..fc237f71 100644 --- a/httprunner/v3/runner.py +++ b/httprunner/v3/runner.py @@ -3,7 +3,7 @@ from typing import List import requests from loguru import logger -from httprunner.v3.parser import build_url +from httprunner.v3.parser import build_url, parse_content from httprunner.v3.response import ResponseObject from httprunner.v3.schema import TestsConfig, TestStep @@ -25,20 +25,23 @@ class TestCaseRunner(object): def run_step(self, step): logger.info(f"run step: {step.name}") - # prepare arguments + # parse request_dict = step.request.dict() - method = request_dict.pop("method") - url_path = request_dict.pop("url") + parsed_request_dict = parse_content(request_dict, step.variables) + + # prepare arguments + method = parsed_request_dict.pop("method") + url_path = parsed_request_dict.pop("url") url = build_url(self.config.base_url, url_path) - request_dict["json"] = request_dict.pop("req_json", {}) + parsed_request_dict["json"] = parsed_request_dict.pop("req_json", {}) logger.info(f"{method} {url}") - logger.debug(f"request kwargs(raw): {request_dict}") + logger.debug(f"request kwargs(raw): {parsed_request_dict}") # request session = self.session or requests.Session() - resp = session.request(method, url, **request_dict) + resp = session.request(method, url, **parsed_request_dict) resp_obj = ResponseObject(resp) # validate