mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-12 11:29:48 +08:00
Merge pull request #3 from debugtalk/master
lastest pull from debugtalk
This commit is contained in:
@@ -38,7 +38,7 @@ To ensure the installation or upgrade is successful, you can execute command `at
|
||||
|
||||
```text
|
||||
$ ate -V
|
||||
ApiTestEngine version: 0.7.5
|
||||
ApiTestEngine version: 0.7.7
|
||||
```
|
||||
|
||||
Execute the command `ate -h` to view command help.
|
||||
@@ -98,9 +98,9 @@ And here is testset example of typical scenario: get `token` at the beginning, a
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -114,7 +114,7 @@ And here is testset example of typical scenario: get `token` at the beginning, a
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
```
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = '0.7.5'
|
||||
__version__ = '0.7.7'
|
||||
@@ -54,7 +54,7 @@ class HttpSession(requests.Session):
|
||||
else:
|
||||
raise ParamsError("base url missed!")
|
||||
|
||||
def request(self, method, url, **kwargs):
|
||||
def request(self, method, url, name=None, **kwargs):
|
||||
"""
|
||||
Constructs and sends a :py:class:`requests.Request`.
|
||||
Returns :py:class:`requests.Response` object.
|
||||
@@ -63,6 +63,8 @@ class HttpSession(requests.Session):
|
||||
method for the new :class:`Request` object.
|
||||
:param url:
|
||||
URL for the new :class:`Request` object.
|
||||
:param name: (optional)
|
||||
Placeholder, make compatible with Locust's HttpSession
|
||||
:param params: (optional)
|
||||
Dictionary or bytes to be sent in the query string for the :class:`Request`.
|
||||
:param data: (optional)
|
||||
|
||||
@@ -34,7 +34,7 @@ class Context(object):
|
||||
self.testcase_variables_mapping = copy.deepcopy(self.testset_shared_variables_mapping)
|
||||
|
||||
self.testcase_parser.bind_functions(self.testcase_functions_config)
|
||||
self.testcase_parser.bind_variables(self.testcase_variables_mapping)
|
||||
self.testcase_parser.update_binded_variables(self.testcase_variables_mapping)
|
||||
|
||||
if level == "testset":
|
||||
self.import_module_items(["ate.built_in"], "testset")
|
||||
@@ -117,7 +117,17 @@ class Context(object):
|
||||
self.testset_shared_variables_mapping[variable_name] = variable_evale_value
|
||||
|
||||
self.testcase_variables_mapping[variable_name] = variable_evale_value
|
||||
self.testcase_parser.bind_variables(self.testcase_variables_mapping)
|
||||
self.testcase_parser.update_binded_variables(self.testcase_variables_mapping)
|
||||
|
||||
def bind_extracted_variables(self, variables):
|
||||
""" bind extracted variables to testset context
|
||||
@param (OrderDict) variables
|
||||
extracted value do not need to evaluate.
|
||||
"""
|
||||
for variable_name, value in variables.items():
|
||||
self.testset_shared_variables_mapping[variable_name] = value
|
||||
self.testcase_variables_mapping[variable_name] = value
|
||||
self.testcase_parser.update_binded_variables(self.testcase_variables_mapping)
|
||||
|
||||
def __update_context_functions_config(self, level, config_mapping):
|
||||
"""
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#coding: utf-8
|
||||
import zmq
|
||||
import os
|
||||
from locust import HttpLocust, TaskSet, task
|
||||
from ate import runner, exception
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import logging
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
|
||||
from ate import exception, utils
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
|
||||
text_extractor_regexp_compile = re.compile(r".*\(.*\).*")
|
||||
|
||||
|
||||
class ResponseObject(object):
|
||||
@@ -10,23 +15,45 @@ class ResponseObject(object):
|
||||
@param (requests.Response instance) resp_obj
|
||||
"""
|
||||
self.resp_obj = resp_obj
|
||||
self.resp_text = resp_obj.text
|
||||
self.resp_body = self.parsed_body()
|
||||
|
||||
def parsed_body(self):
|
||||
try:
|
||||
return self.resp_obj.json()
|
||||
except ValueError:
|
||||
return self.resp_obj.text
|
||||
return self.resp_text
|
||||
|
||||
def parsed_dict(self):
|
||||
return {
|
||||
'status_code': self.resp_obj.status_code,
|
||||
'headers': self.resp_obj.headers,
|
||||
'body': self.parsed_body()
|
||||
'body': self.resp_body
|
||||
}
|
||||
|
||||
def extract_field(self, field, delimiter='.'):
|
||||
""" extract field from requests.Response
|
||||
@param (str) field of requests.Response object, and may be joined by delimiter
|
||||
def _extract_field_with_regex(self, field):
|
||||
""" extract field from response content with regex.
|
||||
requests.Response body could be json or html text.
|
||||
@param (str) field should only be regex string that matched r".*\(.*\).*"
|
||||
e.g.
|
||||
self.resp_text: "LB123abcRB789"
|
||||
field: "LB[\d]*(.*)RB[\d]*"
|
||||
return: abc
|
||||
"""
|
||||
matched = re.search(field, self.resp_text)
|
||||
if not matched:
|
||||
err_msg = "Extractor error: failed to extract data with regex!\n"
|
||||
err_msg += "response body: {}\n".format(self.resp_text)
|
||||
err_msg += "regex: {}\n".format(field)
|
||||
logging.error(err_msg)
|
||||
raise exception.ParamsError(err_msg)
|
||||
|
||||
return matched.group(1)
|
||||
|
||||
def _extract_field_with_delimiter(self, field):
|
||||
""" response content could be json or html text.
|
||||
@param (str) field should be string joined by delimiter.
|
||||
e.g.
|
||||
"status_code"
|
||||
"content"
|
||||
"headers.content-type"
|
||||
@@ -36,28 +63,47 @@ class ResponseObject(object):
|
||||
# string.split(sep=None, maxsplit=-1) -> list of strings
|
||||
# e.g. "content.person.name" => ["content", "person.name"]
|
||||
try:
|
||||
top_query, sub_query = field.split(delimiter, 1)
|
||||
top_query, sub_query = field.split('.', 1)
|
||||
except ValueError:
|
||||
top_query = field
|
||||
sub_query = None
|
||||
|
||||
if top_query in ["body", "content", "text"]:
|
||||
json_content = self.parsed_body()
|
||||
top_query_content = self.parsed_body()
|
||||
else:
|
||||
json_content = getattr(self.resp_obj, top_query)
|
||||
top_query_content = getattr(self.resp_obj, top_query)
|
||||
|
||||
if sub_query:
|
||||
if not isinstance(top_query_content, (dict, CaseInsensitiveDict, list)):
|
||||
err_msg = "Extractor error: failed to extract data with regex!\n"
|
||||
err_msg += "response: {}\n".format(self.parsed_dict())
|
||||
err_msg += "regex: {}\n".format(field)
|
||||
logging.error(err_msg)
|
||||
raise exception.ParamsError(err_msg)
|
||||
|
||||
# e.g. key: resp_headers_content_type, sub_query = "content-type"
|
||||
return utils.query_json(json_content, sub_query)
|
||||
return utils.query_json(top_query_content, sub_query)
|
||||
else:
|
||||
# e.g. key: resp_status_code, resp_content
|
||||
return json_content
|
||||
return top_query_content
|
||||
|
||||
except AttributeError:
|
||||
raise exception.ParseResponseError("failed to extract bind variable in response!")
|
||||
err_msg = "Failed to extract value from response!\n"
|
||||
err_msg += "response: {}\n".format(self.parsed_dict())
|
||||
err_msg += "extract field field: {}\n".format(field)
|
||||
logging.error(err_msg)
|
||||
raise exception.ParamsError(err_msg)
|
||||
|
||||
def extract_field(self, field):
|
||||
""" extract value from requests.Response.
|
||||
"""
|
||||
if text_extractor_regexp_compile.match(field):
|
||||
return self._extract_field_with_regex(field)
|
||||
else:
|
||||
return self._extract_field_with_delimiter(field)
|
||||
|
||||
def extract_response(self, extractors):
|
||||
""" extract content from requests.Response
|
||||
""" extract value from requests.Response and store in OrderedDict.
|
||||
@param (list) extractors
|
||||
[
|
||||
{"resp_status_code": "status_code"},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import logging
|
||||
from collections import OrderedDict
|
||||
|
||||
from ate import exception, response, testcase, utils
|
||||
@@ -84,8 +85,8 @@ class Runner(object):
|
||||
},
|
||||
"body": '{"name": "user", "password": "123456"}'
|
||||
},
|
||||
"extractors": [], # optional
|
||||
"validators": [], # optional
|
||||
"extract": [], # optional
|
||||
"validate": [], # optional
|
||||
"setup": [], # optional
|
||||
"teardown": [] # optional
|
||||
}
|
||||
@@ -96,14 +97,16 @@ class Runner(object):
|
||||
try:
|
||||
url = parsed_request.pop('url')
|
||||
method = parsed_request.pop('method')
|
||||
group_name = parsed_request.pop("group", None)
|
||||
except KeyError:
|
||||
raise exception.ParamsError("URL or METHOD missed!")
|
||||
|
||||
run_times = int(testcase.get("times", 1))
|
||||
extractors = testcase.get("extractors") \
|
||||
or testcase.get("extractor") \
|
||||
extractors = testcase.get("extract") \
|
||||
or testcase.get("extractors") \
|
||||
or testcase.get("extract_binds", [])
|
||||
validators = testcase.get("validators", [])
|
||||
validators = testcase.get("validate") \
|
||||
or testcase.get("validators", [])
|
||||
setup_actions = testcase.get("setup", [])
|
||||
teardown_actions = testcase.get("teardown", [])
|
||||
|
||||
@@ -114,13 +117,24 @@ class Runner(object):
|
||||
for _ in range(run_times):
|
||||
setup_teardown(setup_actions)
|
||||
|
||||
resp = self.http_client_session.request(url=url, method=method, **parsed_request)
|
||||
resp = self.http_client_session.request(
|
||||
method,
|
||||
url,
|
||||
name=group_name,
|
||||
**parsed_request
|
||||
)
|
||||
resp_obj = response.ResponseObject(resp)
|
||||
|
||||
extracted_variables_mapping = resp_obj.extract_response(extractors)
|
||||
self.context.bind_variables(extracted_variables_mapping, level="testset")
|
||||
self.context.bind_extracted_variables(extracted_variables_mapping)
|
||||
|
||||
resp_obj.validate(validators, self.context.get_testcase_variables_mapping())
|
||||
try:
|
||||
resp_obj.validate(validators, self.context.get_testcase_variables_mapping())
|
||||
except (exception.ParamsError, exception.ResponseError, exception.ValidationError):
|
||||
logging.error("Exception occured.")
|
||||
logging.error("HTTP request kwargs: \n{}".format(parsed_request))
|
||||
logging.error("HTTP response content: \n{}".format(resp.text))
|
||||
raise
|
||||
|
||||
setup_teardown(teardown_actions)
|
||||
|
||||
@@ -144,8 +158,8 @@ class Runner(object):
|
||||
"name": "testcase description",
|
||||
"variables": [], # optional, override
|
||||
"request": {},
|
||||
"extractors": {}, # optional
|
||||
"validators": {} # optional
|
||||
"extract": {}, # optional
|
||||
"validate": {} # optional
|
||||
},
|
||||
testcase12
|
||||
]
|
||||
|
||||
@@ -330,11 +330,11 @@ def substitute_variables_with_mapping(content, mapping):
|
||||
class TestcaseParser(object):
|
||||
|
||||
def __init__(self, variables={}, functions={}, file_path=None):
|
||||
self.bind_variables(variables)
|
||||
self.update_binded_variables(variables)
|
||||
self.bind_functions(functions)
|
||||
self.file_path = file_path
|
||||
|
||||
def bind_variables(self, variables):
|
||||
def update_binded_variables(self, variables):
|
||||
""" bind variables to current testcase parser
|
||||
@param (dict) variables, variables binds mapping
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ Suppose we get the following HTTP response.
|
||||
}
|
||||
```
|
||||
|
||||
In `extractors` and `validators`, we can do chain operation to extract data field in HTTP response.
|
||||
In `extract` and `validate`, we can do chain operation to extract data field in HTTP response.
|
||||
|
||||
For instance, if we want to get `Content-Type` in response headers, then we can specify `headers.content-type`; if we want to get `first_name` in response content, we can specify `content.person.name.first_name`.
|
||||
|
||||
@@ -46,10 +46,10 @@ content.person.cities.1
|
||||
```
|
||||
|
||||
```yaml
|
||||
extractors:
|
||||
extract:
|
||||
- content_type: headers.content-type
|
||||
- first_name: content.person.name.first_name
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "headers.content-type", "expected": "application/json"}
|
||||
- {"check": "headers.content-length", "comparator": "gt", "expected": 40}
|
||||
|
||||
@@ -65,7 +65,7 @@ Open your favorite text editor and you can write test cases like this.
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
```
|
||||
@@ -120,9 +120,9 @@ To fix this problem, we should correlate `token` field in the second API test ca
|
||||
app_version: 2.8.6
|
||||
json:
|
||||
sign: 19067cf712265eb5426db8d3664026c1ccea02b9
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -137,12 +137,12 @@ To fix this problem, we should correlate `token` field in the second API test ca
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
```
|
||||
|
||||
As you see, the `token` field is no longer hardcoded, instead it is extracted from the first API request with `extractors` mechanism. In the meanwhile, it is assigned to `token` variable, which can be referenced by the subsequent API requests.
|
||||
As you see, the `token` field is no longer hardcoded, instead it is extracted from the first API request with `extract` mechanism. In the meanwhile, it is assigned to `token` variable, which can be referenced by the subsequent API requests.
|
||||
|
||||
Now we save the test cases to [`quickstart-demo-rev-1.yml`][quickstart-demo-rev-1] and rerun it, and we will find that both API requests to be successful.
|
||||
|
||||
@@ -202,9 +202,9 @@ And then, we can revise our demo test case and reference the functions. Suppose
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -219,7 +219,7 @@ And then, we can revise our demo test case and reference the functions. Suppose
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
```
|
||||
@@ -266,9 +266,9 @@ To handle this case, overall `config` block is supported in `ApiTestEngine`. If
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -282,7 +282,7 @@ To handle this case, overall `config` block is supported in `ApiTestEngine`. If
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
```
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
app_version: 2.8.6
|
||||
json:
|
||||
sign: 19067cf712265eb5426db8d3664026c1ccea02b9
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
app_version: 2.8.6
|
||||
json:
|
||||
sign: 19067cf712265eb5426db8d3664026c1ccea02b9
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -32,6 +32,6 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
@@ -22,9 +22,9 @@
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -38,6 +38,6 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
"sign": "f1219719911caae89ccc301679857ebfda115ca2"
|
||||
}
|
||||
},
|
||||
"extractors": [
|
||||
"extract": [
|
||||
{
|
||||
"token": "content.token"
|
||||
}
|
||||
],
|
||||
"validators": [
|
||||
"validate": [
|
||||
{"check": "status_code", "comparator": "eq", "expected": 200},
|
||||
{"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
]
|
||||
@@ -43,7 +43,7 @@
|
||||
"password": "123456"
|
||||
}
|
||||
},
|
||||
"validators": [
|
||||
"validate": [
|
||||
{"check": "status_code", "comparator": "eq", "expected": 201},
|
||||
{"check": "content.success", "comparator": "eq", "expected": true}
|
||||
]
|
||||
@@ -65,7 +65,7 @@
|
||||
"password": "123456"
|
||||
}
|
||||
},
|
||||
"validators": [
|
||||
"validate": [
|
||||
{"check": "status_code", "comparator": "eq", "expected": 500},
|
||||
{"check": "content.success", "comparator": "eq", "expected": false}
|
||||
]
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
app_version: '2.8.6'
|
||||
json:
|
||||
sign: f1219719911caae89ccc301679857ebfda115ca2
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
|
||||
@@ -45,6 +45,6 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 500}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": false}
|
||||
@@ -16,20 +16,20 @@
|
||||
- test:
|
||||
name: get token
|
||||
api: get_token($user_agent, $device_sn, $os_platform, $app_version)
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
|
||||
- test:
|
||||
name: reset all users
|
||||
api: reset_all($token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 200}
|
||||
- {"check": "content.success", "expected": true}
|
||||
|
||||
- test:
|
||||
name: get user that does not exist
|
||||
api: get_user(1000, $token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 404}
|
||||
- {"check": "content.success", "expected": false}
|
||||
|
||||
@@ -39,14 +39,14 @@
|
||||
- user_name: "user1"
|
||||
- user_password: "123456"
|
||||
api: create_user(1000, $user_name, $user_password, $token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 201}
|
||||
- {"check": "content.success", "expected": true}
|
||||
|
||||
- test:
|
||||
name: get user that has been created
|
||||
api: get_user(1000, $token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 200}
|
||||
- {"check": "content.success", "expected": true}
|
||||
- {"check": "content.data.password", "expected": "123456"}
|
||||
@@ -57,7 +57,7 @@
|
||||
- user_name: "user1"
|
||||
- user_password: "123456"
|
||||
api: create_user(1000, $user_name, $user_password, $token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 500}
|
||||
- {"check": "content.success", "expected": false}
|
||||
|
||||
@@ -67,14 +67,14 @@
|
||||
- user_name: "user1"
|
||||
- user_password: "654321"
|
||||
api: update_user(1000, $user_name, $user_password, $token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 200}
|
||||
- {"check": "content.success", "expected": true}
|
||||
|
||||
- test:
|
||||
name: get user that has been updated
|
||||
api: get_user(1000, $token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 200}
|
||||
- {"check": "content.success", "expected": true}
|
||||
- {"check": "content.data.password", "expected": "654321"}
|
||||
@@ -82,21 +82,21 @@
|
||||
- test:
|
||||
name: get users
|
||||
api: get_users($token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 200}
|
||||
- {"check": "content.count", "expected": 1}
|
||||
|
||||
- test:
|
||||
name: delete user that exists
|
||||
api: delete_user(1000, $token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 200}
|
||||
- {"check": "content.success", "expected": true}
|
||||
|
||||
- test:
|
||||
name: get users
|
||||
api: get_users($token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 200}
|
||||
- {"check": "content.count", "expected": 0}
|
||||
|
||||
@@ -106,13 +106,13 @@
|
||||
- user_name: "user1"
|
||||
- user_password: "123456"
|
||||
api: create_user(1000, $user_name, $user_password, $token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 201}
|
||||
- {"check": "content.success", "expected": true}
|
||||
|
||||
- test:
|
||||
name: get users
|
||||
api: get_users($token)
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "expected": 200}
|
||||
- {"check": "content.count", "expected": 1}
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
json:
|
||||
name: $user_name
|
||||
password: $user_password
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
|
||||
@@ -58,6 +58,6 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 500}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": false}
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: ${get_sign_lambda($user_agent, $device_sn, $os_platform, $app_version)}
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
json:
|
||||
name: $user_name
|
||||
password: $user_password
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
|
||||
@@ -68,6 +68,6 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 500}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": false}
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
app_version: $app_version
|
||||
json:
|
||||
sign: $sign
|
||||
extractors:
|
||||
extract:
|
||||
- token: content.token
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 200}
|
||||
- {"check": "content.token", "comparator": "len_eq", "expected": 16}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
json:
|
||||
name: $user_name
|
||||
password: $user_password
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 201}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": true}
|
||||
|
||||
@@ -59,6 +59,6 @@
|
||||
json:
|
||||
name: "user1"
|
||||
password: "123456"
|
||||
validators:
|
||||
validate:
|
||||
- {"check": "status_code", "comparator": "eq", "expected": 500}
|
||||
- {"check": "content.success", "comparator": "eq", "expected": false}
|
||||
|
||||
@@ -149,6 +149,55 @@ class TestResponse(ApiServerUnittest):
|
||||
"abc"
|
||||
)
|
||||
|
||||
def test_extract_text_response(self):
|
||||
resp = requests.post(
|
||||
url="http://127.0.0.1:5000/customize-response",
|
||||
json={
|
||||
'headers': {
|
||||
'Content-Type': "application/json"
|
||||
},
|
||||
'body': "LB123abcRB789"
|
||||
}
|
||||
)
|
||||
|
||||
extract_binds_list = [
|
||||
{"resp_content_key1": "LB123(.*)RB789"},
|
||||
{"resp_content_key2": "LB[\d]*(.*)RB[\d]*"},
|
||||
{"resp_content_key3": "LB[\d]*(.*)9"}
|
||||
]
|
||||
resp_obj = response.ResponseObject(resp)
|
||||
|
||||
extract_binds_dict = resp_obj.extract_response(extract_binds_list)
|
||||
self.assertEqual(
|
||||
extract_binds_dict["resp_content_key1"],
|
||||
"abc"
|
||||
)
|
||||
self.assertEqual(
|
||||
extract_binds_dict["resp_content_key2"],
|
||||
"abc"
|
||||
)
|
||||
self.assertEqual(
|
||||
extract_binds_dict["resp_content_key3"],
|
||||
"abcRB78"
|
||||
)
|
||||
|
||||
def test_extract_text_response_exception(self):
|
||||
resp = requests.post(
|
||||
url="http://127.0.0.1:5000/customize-response",
|
||||
json={
|
||||
'headers': {
|
||||
'Content-Type': "application/json"
|
||||
},
|
||||
'body': "LB123abcRB789"
|
||||
}
|
||||
)
|
||||
extract_binds_list = [
|
||||
{"resp_content_key1": "LB123.*RB789"}
|
||||
]
|
||||
resp_obj = response.ResponseObject(resp)
|
||||
with self.assertRaises(exception.ParamsError):
|
||||
resp_obj.extract_response(extract_binds_list)
|
||||
|
||||
def test_extract_response_empty(self):
|
||||
resp = requests.post(
|
||||
url="http://127.0.0.1:5000/customize-response",
|
||||
@@ -174,7 +223,7 @@ class TestResponse(ApiServerUnittest):
|
||||
{"resp_content_body": "content.abc"}
|
||||
]
|
||||
resp_obj = response.ResponseObject(resp)
|
||||
with self.assertRaises(exception.ResponseError):
|
||||
with self.assertRaises(exception.ParamsError):
|
||||
resp_obj.extract_response(extract_binds_list)
|
||||
|
||||
def test_validate(self):
|
||||
|
||||
@@ -53,10 +53,10 @@ class TestRunner(ApiServerUnittest):
|
||||
"sign": "f1219719911caae89ccc301679857ebfda115ca2"
|
||||
}
|
||||
},
|
||||
"extractors": [
|
||||
"extract": [
|
||||
{"token": "content.token"}
|
||||
],
|
||||
"validators": [
|
||||
"validate": [
|
||||
{"check": "status_code", "comparator": "eq", "expected": 205},
|
||||
{"check": "content.token", "comparator": "len_eq", "expected": 19}
|
||||
]
|
||||
|
||||
@@ -421,7 +421,7 @@ class TestcaseParserUnittest(unittest.TestCase):
|
||||
self.assertIn("request", testsets_list[0]["config"])
|
||||
self.assertIn("request", testsets_list[0]["testcases"][0])
|
||||
self.assertIn("url", testsets_list[0]["testcases"][0]["request"])
|
||||
self.assertIn("validators", testsets_list[0]["testcases"][0])
|
||||
self.assertIn("validate", testsets_list[0]["testcases"][0])
|
||||
|
||||
def test_substitute_variables_with_mapping(self):
|
||||
content = {
|
||||
|
||||
Reference in New Issue
Block a user