v3 feat: support extract session variables

This commit is contained in:
debugtalk
2020-04-20 13:26:40 +08:00
parent 50aa3b4880
commit ab506b8b74
4 changed files with 41 additions and 17 deletions

View File

@@ -10,7 +10,7 @@ teststeps:
name: get with params name: get with params
variables: variables:
foo1: bar1 foo1: bar1
foo2: bar2 foo2: session_bar2
request: request:
method: GET method: GET
url: /get url: /get
@@ -19,24 +19,27 @@ teststeps:
foo2: $foo2 foo2: $foo2
headers: headers:
User-Agent: HttpRunner/3.0 User-Agent: HttpRunner/3.0
extract:
session_foo2: "body.args.foo2"
validate: validate:
- eq: ["status_code", 200] - eq: ["status_code", 200]
- eq: ["body.args.foo1", "session_bar1"] - eq: ["body.args.foo1", "session_bar1"]
- eq: ["body.args.foo2", "bar2"] - eq: ["body.args.foo2", "session_bar2"]
- -
name: post raw text name: post raw text
variables: variables:
foo1: "hello world" foo1: "hello world"
foo3: "$session_foo2"
request: request:
method: POST method: POST
url: /post url: /post
headers: headers:
User-Agent: HttpRunner/3.0 User-Agent: HttpRunner/3.0
Content-Type: "text/plain" Content-Type: "text/plain"
data: "This is expected to be sent back as part of response body: $foo1." data: "This is expected to be sent back as part of response body: $foo1-$foo3."
validate: validate:
- eq: ["status_code", 200] - eq: ["status_code", 200]
- eq: ["body.data", "This is expected to be sent back as part of response body: session_bar1."] - eq: ["body.data", "This is expected to be sent back as part of response body: session_bar1-session_bar2."]
- -
name: post form data name: post form data
variables: variables:

View File

@@ -17,7 +17,7 @@ class TestCaseRequestMethodsWithVariables(TestCaseRunner):
"name": "get with params", "name": "get with params",
"variables": { "variables": {
"foo1": "bar1", "foo1": "bar1",
"foo2": "bar2" "foo2": "session_bar2"
}, },
"request": { "request": {
"method": "GET", "method": "GET",
@@ -30,21 +30,25 @@ class TestCaseRequestMethodsWithVariables(TestCaseRunner):
"User-Agent": "HttpRunner/3.0" "User-Agent": "HttpRunner/3.0"
} }
}, },
"extract": {
"session_foo2": "body.args.foo2"
},
"validate": [ "validate": [
{"eq": ["status_code", 200]}, {"eq": ["status_code", 200]},
{"eq": ["body.args.foo1", "session_bar1"]}, {"eq": ["body.args.foo1", "session_bar1"]},
{"eq": ["body.args.foo2", "bar2"]} {"eq": ["body.args.foo2", "session_bar2"]}
] ]
}), }),
TestStep(**{ TestStep(**{
"name": "post raw text", "name": "post raw text",
"variables": { "variables": {
"foo1": "hello world" "foo1": "hello world",
"foo3": "$session_foo2"
}, },
"request": { "request": {
"method": "POST", "method": "POST",
"url": "/post", "url": "/post",
"data": "This is expected to be sent back as part of response body: $foo1.", "data": "This is expected to be sent back as part of response body: $foo1-$foo3.",
"headers": { "headers": {
"User-Agent": "HttpRunner/3.0", "User-Agent": "HttpRunner/3.0",
"Content-Type": "text/plain" "Content-Type": "text/plain"
@@ -52,7 +56,10 @@ class TestCaseRequestMethodsWithVariables(TestCaseRunner):
}, },
"validate": [ "validate": [
{"eq": ["status_code", 200]}, {"eq": ["status_code", 200]},
{"eq": ["body.data", "This is expected to be sent back as part of response body: session_bar1."]}, {"eq": [
"body.data",
"This is expected to be sent back as part of response body: session_bar1-session_bar2."
]},
] ]
}), }),
TestStep(**{ TestStep(**{

View File

@@ -3,6 +3,7 @@ from typing import Any, Set, Text
from typing import Dict from typing import Dict
from httprunner.v3 import exceptions from httprunner.v3 import exceptions
from httprunner.v3.exceptions import VariableNotFound
absolute_http_url_regexp = re.compile(r"^https?://", re.I) absolute_http_url_regexp = re.compile(r"^https?://", re.I)
@@ -98,7 +99,10 @@ def parse_string_variables(content, variables_mapping):
""" """
variables_list = extract_variables(content) variables_list = extract_variables(content)
for variable_name in variables_list: for variable_name in variables_list:
variable_value = variables_mapping[variable_name] try:
variable_value = variables_mapping[variable_name]
except KeyError:
raise VariableNotFound(f"{variable_name} not in {variables_mapping}")
# TODO: replace variable label from $var to {{var}} # TODO: replace variable label from $var to {{var}}
if f"${variable_name}" == content: if f"${variable_name}" == content:
@@ -158,20 +162,24 @@ def parse_content(content: Any, variables_mapping: Dict[str, Any] = None, functi
return content return content
def parse_variables_mapping(variables_mapping: Dict[str, Any]): def parse_variables_mapping(variables_mapping: Dict[Text, Any]) -> Dict[Text, Any]:
parsed_variables: Dict[str, Any] = {} parsed_variables: Dict[Text, Any] = {}
while len(parsed_variables) != len(variables_mapping): while len(parsed_variables) != len(variables_mapping):
for var_name in variables_mapping: for var_name in variables_mapping:
var_value = variables_mapping[var_name]
# variables = extract_variables(var_value)
if var_name in parsed_variables: if var_name in parsed_variables:
continue continue
parsed_value = parse_content(var_value, parsed_variables) var_value = variables_mapping[var_name]
# variables = extract_variables(var_value)
try:
parsed_value = parse_content(var_value, parsed_variables)
except VariableNotFound:
continue
parsed_variables[var_name] = parsed_value parsed_variables[var_name] = parsed_value
return parsed_variables return parsed_variables

View File

@@ -3,7 +3,7 @@ from typing import List
import requests import requests
from loguru import logger from loguru import logger
from httprunner.v3.parser import build_url, parse_content from httprunner.v3.parser import build_url, parse_content, parse_variables_mapping
from httprunner.v3.response import ResponseObject from httprunner.v3.response import ResponseObject
from httprunner.v3.schema import TestsConfig, TestStep from httprunner.v3.schema import TestsConfig, TestStep
@@ -57,9 +57,15 @@ class TestCaseRunner(object):
"""main entrance""" """main entrance"""
session_variables = {} session_variables = {}
for step in self.teststeps: for step in self.teststeps:
# update with config variables
step.variables.update(self.config.variables) step.variables.update(self.config.variables)
# update with session variables extracted from former step
step.variables.update(session_variables) step.variables.update(session_variables)
# parse variables
step.variables = parse_variables_mapping(step.variables)
# run step
extract_mapping = self.run_step(step) extract_mapping = self.run_step(step)
# save extracted variables to session variables
session_variables.update(extract_mapping) session_variables.update(extract_mapping)
def run(self): def run(self):