mirror of
https://github.com/httprunner/httprunner.git
synced 2026-08-28 19:47:14 +08:00
change: replace jsonschema validation with pydantic
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
**Changed**
|
**Changed**
|
||||||
|
|
||||||
|
- replace jsonschema validation with pydantic
|
||||||
- remove compatibility with testcase/testsuite format v1
|
- remove compatibility with testcase/testsuite format v1
|
||||||
|
|
||||||
## 3.0.1 (2020-03-24)
|
## 3.0.1 (2020-03-24)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
__version__ = "3.0.1"
|
__version__ = "3.0.2"
|
||||||
__description__ = "One-stop solution for HTTP(S) testing."
|
__description__ = "One-stop solution for HTTP(S) testing."
|
||||||
|
|
||||||
__all__ = ["__version__", "__description__"]
|
__all__ = ["__version__", "__description__"]
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ def load_test_file(path: str) -> dict:
|
|||||||
loaded_content["type"] = "testsuite"
|
loaded_content["type"] = "testsuite"
|
||||||
|
|
||||||
elif "teststeps" in raw_content:
|
elif "teststeps" in raw_content:
|
||||||
# file_type: testcase (format version 2)
|
# file_type: testcase
|
||||||
loaded_content = load_testcase(raw_content)
|
loaded_content = load_testcase(raw_content)
|
||||||
loaded_content["path"] = path
|
loaded_content["path"] = path
|
||||||
loaded_content["type"] = "testcase"
|
loaded_content["type"] = "testcase"
|
||||||
@@ -329,12 +329,12 @@ def load_project_data(test_path, dot_env_path=None):
|
|||||||
# locate PWD and load debugtalk.py functions
|
# locate PWD and load debugtalk.py functions
|
||||||
project_mapping["PWD"] = project_working_directory
|
project_mapping["PWD"] = project_working_directory
|
||||||
project_mapping["functions"] = debugtalk_functions
|
project_mapping["functions"] = debugtalk_functions
|
||||||
project_mapping["test_path"] = os.path.abspath(test_path)[len(project_working_directory)+1:]
|
project_mapping["test_path"] = os.path.abspath(test_path)[len(project_working_directory) + 1:]
|
||||||
|
|
||||||
return project_mapping
|
return project_mapping
|
||||||
|
|
||||||
|
|
||||||
def load_cases(path, dot_env_path=None):
|
def load_cases(path: str, dot_env_path: str = None):
|
||||||
""" load testcases from file path, extend and merge with api/testcase definitions.
|
""" load testcases from file path, extend and merge with api/testcase definitions.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
+17
-44
@@ -1,70 +1,43 @@
|
|||||||
import io
|
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
|
|
||||||
import jsonschema
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
from pydantic import ValidationError
|
||||||
|
|
||||||
from httprunner import exceptions
|
from httprunner import exceptions
|
||||||
|
from httprunner.schema import Api, TestCase, TestSuite
|
||||||
schemas_root_dir = os.path.join(os.path.dirname(__file__), "schemas")
|
|
||||||
common_schema_path = os.path.join(schemas_root_dir, "common.schema.json")
|
|
||||||
api_schema_path = os.path.join(schemas_root_dir, "api.schema.json")
|
|
||||||
testcase_schema_path = os.path.join(schemas_root_dir, "testcase.schema.json")
|
|
||||||
testsuite_schema_path = os.path.join(schemas_root_dir, "testsuite.schema.json")
|
|
||||||
|
|
||||||
with io.open(api_schema_path, encoding='utf-8') as f:
|
|
||||||
api_schema = json.load(f)
|
|
||||||
|
|
||||||
with io.open(common_schema_path, encoding='utf-8') as f:
|
|
||||||
if platform.system() == "Windows":
|
|
||||||
absolute_base_path = 'file:///' + os.path.abspath(schemas_root_dir).replace("\\", "/") + '/'
|
|
||||||
else:
|
|
||||||
# Linux, Darwin
|
|
||||||
absolute_base_path = "file://" + os.path.abspath(schemas_root_dir) + "/"
|
|
||||||
|
|
||||||
common_schema = json.load(f)
|
|
||||||
resolver = jsonschema.RefResolver(absolute_base_path, common_schema)
|
|
||||||
|
|
||||||
with io.open(testcase_schema_path, encoding='utf-8') as f:
|
|
||||||
testcase_schema = json.load(f)
|
|
||||||
|
|
||||||
with io.open(testsuite_schema_path, encoding='utf-8') as f:
|
|
||||||
testsuite_schema = json.load(f)
|
|
||||||
|
|
||||||
|
|
||||||
class JsonSchemaChecker(object):
|
class JsonSchemaChecker(object):
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def validate_format(content, scheme):
|
|
||||||
""" check api/testcase/testsuite format if valid
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
jsonschema.validate(content, scheme, resolver=resolver)
|
|
||||||
except jsonschema.exceptions.ValidationError as ex:
|
|
||||||
logger.error(str(ex))
|
|
||||||
raise exceptions.FileFormatError
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validate_api_format(content):
|
def validate_api_format(content):
|
||||||
""" check api format if valid
|
""" check api format if valid
|
||||||
"""
|
"""
|
||||||
return JsonSchemaChecker.validate_format(content, api_schema)
|
try:
|
||||||
|
Api.parse_obj(content)
|
||||||
|
except ValidationError as ex:
|
||||||
|
logger.error(ex)
|
||||||
|
raise exceptions.FileFormatError
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validate_testcase_format(content):
|
def validate_testcase_format(content):
|
||||||
""" check testcase format if valid
|
""" check testcase format if valid
|
||||||
"""
|
"""
|
||||||
return JsonSchemaChecker.validate_format(content, testcase_schema)
|
try:
|
||||||
|
TestCase.parse_obj(content)
|
||||||
|
except ValidationError as ex:
|
||||||
|
logger.error(ex)
|
||||||
|
raise exceptions.FileFormatError
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validate_testsuite_format(content):
|
def validate_testsuite_format(content):
|
||||||
""" check testsuite format if valid
|
""" check testsuite format if valid
|
||||||
"""
|
"""
|
||||||
return JsonSchemaChecker.validate_format(content, testsuite_schema)
|
try:
|
||||||
|
TestSuite.parse_obj(content)
|
||||||
|
except ValidationError as ex:
|
||||||
|
logger.error(ex)
|
||||||
|
raise exceptions.FileFormatError
|
||||||
|
|
||||||
|
|
||||||
def is_test_path(path):
|
def is_test_path(path):
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema",
|
|
||||||
"description": "httprunner api schema definition",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"$ref": "common.schema.json#/definitions/name"
|
|
||||||
},
|
|
||||||
"base_url": {
|
|
||||||
"$ref": "common.schema.json#/definitions/base_url"
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"$ref": "common.schema.json#/definitions/variables"
|
|
||||||
},
|
|
||||||
"request": {
|
|
||||||
"$ref": "common.schema.json#/definitions/request"
|
|
||||||
},
|
|
||||||
"setup_hooks": {
|
|
||||||
"$ref": "common.schema.json#/definitions/hook"
|
|
||||||
},
|
|
||||||
"teardown_hooks": {
|
|
||||||
"$ref": "common.schema.json#/definitions/hook"
|
|
||||||
},
|
|
||||||
"extract": {
|
|
||||||
"$ref": "common.schema.json#/definitions/extract"
|
|
||||||
},
|
|
||||||
"validate": {
|
|
||||||
"$ref": "common.schema.json#/definitions/validate"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"request"
|
|
||||||
],
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"name": "demo api",
|
|
||||||
"variables": {
|
|
||||||
"var1": "value1",
|
|
||||||
"var2": "value2"
|
|
||||||
},
|
|
||||||
"request": {
|
|
||||||
"url": "/api/path/$var1",
|
|
||||||
"method": "POST",
|
|
||||||
"headers": {
|
|
||||||
"Content-Type": "application/json"
|
|
||||||
},
|
|
||||||
"json": {
|
|
||||||
"key": "$var2"
|
|
||||||
},
|
|
||||||
"validate": [
|
|
||||||
{
|
|
||||||
"eq": ["status_code", 200]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,392 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema",
|
|
||||||
"description": "common json schema definitions for httprunner api/testcase/testsuite",
|
|
||||||
"definitions": {
|
|
||||||
"name": {
|
|
||||||
"description": "used as api/teststep/testcase/testsuite identification",
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"basic test for httpbin"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"base_url": {
|
|
||||||
"description": "The base_url will be used with relative URI",
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"https://httpbin.org"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"description": "define variables for api/teststep/testcase/testsuite",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"var1": "value1",
|
|
||||||
"var2": "value2"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"maxProperties": 1,
|
|
||||||
"minProperties": 1
|
|
||||||
},
|
|
||||||
"examples": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"var1": "value1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"var2": "value2"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^\\$.*",
|
|
||||||
"examples": [
|
|
||||||
"$prepared_variables",
|
|
||||||
"${prepare_variables()}",
|
|
||||||
"${prepare_variables($a, $b)}"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"verify": {
|
|
||||||
"description": "whether to verify the server’s TLS certificate",
|
|
||||||
"type": "boolean",
|
|
||||||
"examples": [
|
|
||||||
true,
|
|
||||||
false
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hook": {
|
|
||||||
"description": "used to define setup_hooks/teardown_hooks for api/teststep/testcase",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "call setup/teardown hook functions, return nothing",
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
[
|
|
||||||
"${sleep(2)}",
|
|
||||||
"${hook_print(setup)}",
|
|
||||||
"${modify_request_json($request, android)}",
|
|
||||||
"${alter_response($response)}"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "call setup/teardown hook functions, return value and assign to variable",
|
|
||||||
"type": "object",
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"total": "${sum_two(1, 5)}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filed_name": "get_decoded_response_field($response)"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"description": "used in testcase/testsuite to configure common fields",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"$ref": "#/definitions/name"
|
|
||||||
},
|
|
||||||
"base_url": {
|
|
||||||
"$ref": "#/definitions/base_url"
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"$ref": "#/definitions/variables"
|
|
||||||
},
|
|
||||||
"setup_hooks": {
|
|
||||||
"$ref": "#/definitions/hook"
|
|
||||||
},
|
|
||||||
"teardown_hooks": {
|
|
||||||
"$ref": "#/definitions/hook"
|
|
||||||
},
|
|
||||||
"verify": {
|
|
||||||
"$ref": "#/definitions/verify"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["name"]
|
|
||||||
},
|
|
||||||
"request": {
|
|
||||||
"description": "used to define a api request. properties is the same as python package `requests.request`",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"method": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "request method",
|
|
||||||
"enum": [
|
|
||||||
"GET",
|
|
||||||
"POST",
|
|
||||||
"OPTIONS",
|
|
||||||
"HEAD",
|
|
||||||
"PUT",
|
|
||||||
"PATCH",
|
|
||||||
"DELETE",
|
|
||||||
"CONNECT",
|
|
||||||
"TRACE"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"url": {
|
|
||||||
"description": "request url, may be absolute or relative URI",
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"http://httpbin.org/get?a=1&b=2",
|
|
||||||
"/get?a=1&b=2",
|
|
||||||
"get?a=1&b=2"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"params": {
|
|
||||||
"description": "query string for request url",
|
|
||||||
"type": "object",
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"data": {
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"description": "request body in json format",
|
|
||||||
"type": "object",
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "request body in application/x-www-form-urlencoded format",
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"a=1&b=2"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "request body prepared with function, or reference a variable",
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"$post_data",
|
|
||||||
"${prepare_data($a, $b)}"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"json": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "request body in json format",
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "request body prepared with function, or reference a variable",
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^\\$.*",
|
|
||||||
"examples": [
|
|
||||||
"$post_data",
|
|
||||||
"${prepare_post_data($a, $b)}"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"headers": {
|
|
||||||
"description": "request headers",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"description": "request headers in json format",
|
|
||||||
"type": "object",
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"User-Agent": "python-requests/2.18.4",
|
|
||||||
"Content-Type": "application/json"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "request headers prepared with function, or reference a variable",
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"$prepared_headers",
|
|
||||||
"${prepare_headers($a, $b)}"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"cookies": {
|
|
||||||
"description": "request cookies",
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"files": {
|
|
||||||
"description": "request files, used to upload files",
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"auth": {
|
|
||||||
"description": "Auth tuple to enable Basic/Digest/Custom HTTP Auth.",
|
|
||||||
"type": "array"
|
|
||||||
},
|
|
||||||
"timeout": {
|
|
||||||
"description": "How many seconds to wait for the server to send data before giving up",
|
|
||||||
"type": "number",
|
|
||||||
"examples": [
|
|
||||||
120
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"allow_redirects": {
|
|
||||||
"description": "Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to True",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"proxies": {
|
|
||||||
"description": "Dictionary mapping protocol to the URL of the proxy",
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"verify": {
|
|
||||||
"description": "configure verify for current api/teststep",
|
|
||||||
"$ref": "#/definitions/verify"
|
|
||||||
},
|
|
||||||
"stream": {
|
|
||||||
"description": "if False, the response content will be immediately downloaded.",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"upload": {
|
|
||||||
"description": "upload files",
|
|
||||||
"type": "object",
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"file": "data/file_to_upload",
|
|
||||||
"md5": "123"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"method",
|
|
||||||
"url"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"extract": {
|
|
||||||
"description": "used to extract session variables for later requests",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"patternProperties": {
|
|
||||||
"^[A-Za-z_][A-Za-z0-9_]*$": {
|
|
||||||
"description": "extraction rule for session variable, maybe in jsonpath/regex/jmespath",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"code__by_jsonpath": "$.code",
|
|
||||||
"item_id__by_jsonpath": "$..items.*.id",
|
|
||||||
"var_name__by_regex": "\"LB[\\d]*(.*)RB[\\d]*\"",
|
|
||||||
"content_type": "headers.content-type",
|
|
||||||
"first_name": "content.person.name.first_name"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"patternProperties": {
|
|
||||||
"^[A-Za-z_][A-Za-z0-9_]*$": {
|
|
||||||
"description": "extraction rule for session variable, maybe in jsonpath/regex/jmespath",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minProperties": 1,
|
|
||||||
"maxProperties": 1
|
|
||||||
},
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"code__by_jsonpath": "$.code"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"item_id__by_jsonpath": "$..items.*.id"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"var_name__by_regex": "\"LB[\\d]*(.*)RB[\\d]*\""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content_type": "headers.content-type"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"first_name": "content.person.name.first_name"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"validate": {
|
|
||||||
"description": "used to validate response fields",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"description": "one validator definition",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"check": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"comparator": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"expect": {
|
|
||||||
"description": "expected value"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["check", "expect"],
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"check": "body.code",
|
|
||||||
"comparator": "gt",
|
|
||||||
"expect": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"check": "status_code",
|
|
||||||
"expect": 200
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"patternProperties": {
|
|
||||||
"^[A-Za-z_][A-Za-z0-9_]*$": {
|
|
||||||
"description": "validate_func_name: [check_value, expect_value]",
|
|
||||||
"type": "array",
|
|
||||||
"minItems": 2,
|
|
||||||
"maxItems": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"eq": ["status_code", 200]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gt": ["body.code", 0]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,184 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema",
|
|
||||||
"description": "httprunner testcase schema definition",
|
|
||||||
"type": "object",
|
|
||||||
"definitions": {
|
|
||||||
"teststep": {
|
|
||||||
"type": "object",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"$ref": "common.schema.json#/definitions/name"
|
|
||||||
},
|
|
||||||
"request": {
|
|
||||||
"description": "define api request directly",
|
|
||||||
"$ref": "common.schema.json#/definitions/request"
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"$ref": "common.schema.json#/definitions/variables"
|
|
||||||
},
|
|
||||||
"extract": {
|
|
||||||
"$ref": "common.schema.json#/definitions/extract"
|
|
||||||
},
|
|
||||||
"validate": {
|
|
||||||
"$ref": "common.schema.json#/definitions/validate"
|
|
||||||
},
|
|
||||||
"setup_hooks": {
|
|
||||||
"$ref": "common.schema.json#/definitions/hook"
|
|
||||||
},
|
|
||||||
"teardown_hooks": {
|
|
||||||
"$ref": "common.schema.json#/definitions/hook"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"request"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"$ref": "common.schema.json#/definitions/name"
|
|
||||||
},
|
|
||||||
"api": {
|
|
||||||
"description": "api reference, value is api file relative path",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"$ref": "common.schema.json#/definitions/variables"
|
|
||||||
},
|
|
||||||
"extract": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$ref": "common.schema.json#/definitions/extract"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"validate": {
|
|
||||||
"$ref": "common.schema.json#/definitions/validate"
|
|
||||||
},
|
|
||||||
"setup_hooks": {
|
|
||||||
"$ref": "common.schema.json#/definitions/hook"
|
|
||||||
},
|
|
||||||
"teardown_hooks": {
|
|
||||||
"$ref": "common.schema.json#/definitions/hook"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"api"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"$ref": "common.schema.json#/definitions/name"
|
|
||||||
},
|
|
||||||
"testcase": {
|
|
||||||
"description": "testcase reference, value is testcase file relative path",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"$ref": "common.schema.json#/definitions/variables"
|
|
||||||
},
|
|
||||||
"extract": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"setup_hooks": {
|
|
||||||
"$ref": "common.schema.json#/definitions/hook"
|
|
||||||
},
|
|
||||||
"teardown_hooks": {
|
|
||||||
"$ref": "common.schema.json#/definitions/hook"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"testcase"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"config": {
|
|
||||||
"$ref": "common.schema.json#/definitions/config"
|
|
||||||
},
|
|
||||||
"teststeps": {
|
|
||||||
"description": "teststep of a testcase",
|
|
||||||
"type": "array",
|
|
||||||
"minItems": 1,
|
|
||||||
"items": {
|
|
||||||
"$ref": "testcase.schema.json#/definitions/teststep"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"config",
|
|
||||||
"teststeps"
|
|
||||||
],
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"config": {
|
|
||||||
"name": "testcase name"
|
|
||||||
},
|
|
||||||
"teststeps": [
|
|
||||||
{
|
|
||||||
"name": "api 1",
|
|
||||||
"api": "/path/to/api1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "api 2",
|
|
||||||
"api": "/path/to/api2"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"config": {
|
|
||||||
"name": "demo testcase",
|
|
||||||
"variables": {
|
|
||||||
"device_sn": "ABC",
|
|
||||||
"username": "${ENV(USERNAME)}",
|
|
||||||
"password": "${ENV(PASSWORD)}"
|
|
||||||
},
|
|
||||||
"base_url": "http://127.0.0.1:5000"
|
|
||||||
},
|
|
||||||
"teststeps": [
|
|
||||||
{
|
|
||||||
"name": "demo step 1",
|
|
||||||
"api": "path/to/api1.yml",
|
|
||||||
"variables": {
|
|
||||||
"user_agent": "iOS/10.3",
|
|
||||||
"device_sn": "$device_sn"
|
|
||||||
},
|
|
||||||
"extract": [
|
|
||||||
{
|
|
||||||
"token": "content.token"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"validate": [
|
|
||||||
{
|
|
||||||
"eq": ["status_code", 200]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "demo step 2",
|
|
||||||
"api": "path/to/api2.yml",
|
|
||||||
"variables": {
|
|
||||||
"token": "$token"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema",
|
|
||||||
"description": "httprunner testsuite schema definition",
|
|
||||||
"type": "object",
|
|
||||||
"definitions": {
|
|
||||||
"testcase": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"$ref": "common.schema.json#/definitions/name"
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"$ref": "common.schema.json#/definitions/variables"
|
|
||||||
},
|
|
||||||
"parameters": {
|
|
||||||
"description": "generate cartesian product variables with parameters, each group of variables will be run once",
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"testcase": {
|
|
||||||
"description": "testcase reference, value is testcase file relative path",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"testcase"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"config": {
|
|
||||||
"$ref": "common.schema.json#/definitions/config"
|
|
||||||
},
|
|
||||||
"testcases": {
|
|
||||||
"description": "testcase of a testsuite",
|
|
||||||
"type": "array",
|
|
||||||
"minItems": 1,
|
|
||||||
"items": {
|
|
||||||
"$ref": "testsuite.schema.json#/definitions/testcase"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"config",
|
|
||||||
"testcases"
|
|
||||||
],
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"config": {
|
|
||||||
"name": "testsuite name"
|
|
||||||
},
|
|
||||||
"testcases": [
|
|
||||||
{
|
|
||||||
"name": "testcase 1",
|
|
||||||
"testcase": "/path/to/testcase1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "testcase 2",
|
|
||||||
"testcase": "/path/to/testcase2"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"config": {
|
|
||||||
"name": "demo testsuite",
|
|
||||||
"variables": {
|
|
||||||
"device_sn": "XYZ"
|
|
||||||
},
|
|
||||||
"base_url": "http://127.0.0.1:5000"
|
|
||||||
},
|
|
||||||
"testcases": [
|
|
||||||
{
|
|
||||||
"name": "call demo_testcase with data 1",
|
|
||||||
"testcase": "path/to/demo_testcase.yml",
|
|
||||||
"variables": {
|
|
||||||
"device_sn": "$device_sn"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "call demo_testcase with data 2",
|
|
||||||
"testcase": "path/to/demo_testcase.yml",
|
|
||||||
"variables": {
|
|
||||||
"device_sn": "$device_sn"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1 +1,3 @@
|
|||||||
|
from .api import Api
|
||||||
from .testcase import ProjectMeta, TestCase, TestCases
|
from .testcase import ProjectMeta, TestCase, TestCases
|
||||||
|
from .testsuite import TestSuite
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from httprunner.schema import common
|
from httprunner.schema import common
|
||||||
|
|
||||||
@@ -7,8 +7,8 @@ class Api(BaseModel):
|
|||||||
name: common.Name
|
name: common.Name
|
||||||
request: common.Request
|
request: common.Request
|
||||||
variables: common.Variables
|
variables: common.Variables
|
||||||
base_url: common.BaseUrl
|
base_url: common.BaseUrl = ""
|
||||||
setup_hooks: common.Hook
|
setup_hooks: common.Hook = []
|
||||||
teardown_hooks: common.Hook
|
teardown_hooks: common.Hook = []
|
||||||
extract: common.Extract
|
extract: common.Extract = {}
|
||||||
validate: common.Validate
|
validation: common.Validate = Field([], alias="validate")
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Dict, List, Any, Tuple
|
from typing import Dict, List, Any
|
||||||
|
|
||||||
from pydantic import BaseModel, HttpUrl, Field
|
from pydantic import BaseModel, HttpUrl, Field
|
||||||
|
|
||||||
Name = str
|
Name = str
|
||||||
Url = HttpUrl
|
Url = str
|
||||||
BaseUrl = str
|
BaseUrl = HttpUrl
|
||||||
Variables = Dict[str, Any]
|
Variables = Dict[str, Any]
|
||||||
Headers = Dict[str, str]
|
Headers = Dict[str, str]
|
||||||
Verify = bool
|
Verify = bool
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ class ProjectMeta(BaseModel):
|
|||||||
|
|
||||||
class TestStep(BaseModel):
|
class TestStep(BaseModel):
|
||||||
name: common.Name
|
name: common.Name
|
||||||
request: common.Request
|
api: str = None # TODO: replace with FilePath
|
||||||
|
request: common.Request = None
|
||||||
extract: Dict[str, str] = {}
|
extract: Dict[str, str] = {}
|
||||||
validation: common.Validate = Field([], alias="validate")
|
validation: common.Validate = Field([], alias="validate")
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from httprunner.schema import common, TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestSuite(BaseModel):
|
||||||
|
config: common.TestsConfig
|
||||||
|
testcases: List[TestCase]
|
||||||
Generated
+1
-128
@@ -12,20 +12,6 @@ version = "0.2.2"
|
|||||||
python = "<3.7"
|
python = "<3.7"
|
||||||
version = "2.4"
|
version = "2.4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Classes Without Boilerplate"
|
|
||||||
name = "attrs"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "19.3.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"]
|
|
||||||
dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"]
|
|
||||||
docs = ["sphinx", "zope.interface"]
|
|
||||||
tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "Python package for providing Mozilla's CA Bundle."
|
description = "Python package for providing Mozilla's CA Bundle."
|
||||||
@@ -176,22 +162,6 @@ optional = false
|
|||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.11"
|
version = "0.11"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Read metadata from Python packages"
|
|
||||||
marker = "python_version < \"3.8\""
|
|
||||||
name = "importlib-metadata"
|
|
||||||
optional = false
|
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
|
||||||
version = "1.3.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
zipp = ">=0.5"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
docs = ["sphinx", "rst.linker"]
|
|
||||||
testing = ["packaging", "importlib-resources"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Various helpers to pass data to untrusted environments and back."
|
description = "Various helpers to pass data to untrusted environments and back."
|
||||||
@@ -222,28 +192,6 @@ optional = false
|
|||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.82"
|
version = "0.82"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "An implementation of JSON Schema validation for Python"
|
|
||||||
name = "jsonschema"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.2.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
attrs = ">=17.4.0"
|
|
||||||
pyrsistent = ">=0.14.0"
|
|
||||||
setuptools = "*"
|
|
||||||
six = ">=1.11.0"
|
|
||||||
|
|
||||||
[package.dependencies.importlib-metadata]
|
|
||||||
python = "<3.8"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"]
|
|
||||||
format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "Python logging made (stupidly) simple"
|
description = "Python logging made (stupidly) simple"
|
||||||
@@ -271,18 +219,6 @@ optional = false
|
|||||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "More routines for operating on iterables, beyond itertools"
|
|
||||||
marker = "python_version < \"3.8\""
|
|
||||||
name = "more-itertools"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "5.0.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
six = ">=1.0.0,<2.0.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "Data validation and settings management using python 3.6 type hinting"
|
description = "Data validation and settings management using python 3.6 type hinting"
|
||||||
@@ -301,17 +237,6 @@ dotenv = ["python-dotenv (>=0.10.4)"]
|
|||||||
email = ["email-validator (>=1.0.3)"]
|
email = ["email-validator (>=1.0.3)"]
|
||||||
typing_extensions = ["typing-extensions (>=3.7.2)"]
|
typing_extensions = ["typing-extensions (>=3.7.2)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Persistent/Functional/Immutable data structures"
|
|
||||||
name = "pyrsistent"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.15.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
six = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "YAML parser and emitter for Python"
|
description = "YAML parser and emitter for Python"
|
||||||
@@ -349,14 +274,6 @@ version = "0.9.1"
|
|||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
requests = ">=2.0.1,<3.0.0"
|
requests = ">=2.0.1,<3.0.0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Python 2 and 3 compatibility utilities"
|
|
||||||
name = "six"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
|
||||||
version = "1.13.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "The little ASGI library that shines."
|
description = "The little ASGI library that shines."
|
||||||
@@ -438,24 +355,8 @@ version = "1.0.1"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"]
|
dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
|
||||||
marker = "python_version < \"3.8\""
|
|
||||||
name = "zipp"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7"
|
|
||||||
version = "0.6.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
more-itertools = "*"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
|
||||||
testing = ["pathlib2", "contextlib2", "unittest2"]
|
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
content-hash = "8ef61f687de82f9bd0c92c521e2cc890454a4da6ca7f80d0f30973551540c4ae"
|
content-hash = "ff30b34e5d7a0934029a6ea20ebd43fc9ea769c4bbb2e63890de6d399d756da0"
|
||||||
python-versions = "^3.6"
|
python-versions = "^3.6"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
@@ -463,10 +364,6 @@ aiocontextvars = [
|
|||||||
{file = "aiocontextvars-0.2.2-py2.py3-none-any.whl", hash = "sha256:885daf8261818767d8f7cbd79f9d4482d118f024b6586ef6e67980236a27bfa3"},
|
{file = "aiocontextvars-0.2.2-py2.py3-none-any.whl", hash = "sha256:885daf8261818767d8f7cbd79f9d4482d118f024b6586ef6e67980236a27bfa3"},
|
||||||
{file = "aiocontextvars-0.2.2.tar.gz", hash = "sha256:f027372dc48641f683c559f247bd84962becaacdc9ba711d583c3871fb5652aa"},
|
{file = "aiocontextvars-0.2.2.tar.gz", hash = "sha256:f027372dc48641f683c559f247bd84962becaacdc9ba711d583c3871fb5652aa"},
|
||||||
]
|
]
|
||||||
attrs = [
|
|
||||||
{file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"},
|
|
||||||
{file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"},
|
|
||||||
]
|
|
||||||
certifi = [
|
certifi = [
|
||||||
{file = "certifi-2019.11.28-py2.py3-none-any.whl", hash = "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3"},
|
{file = "certifi-2019.11.28-py2.py3-none-any.whl", hash = "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3"},
|
||||||
{file = "certifi-2019.11.28.tar.gz", hash = "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"},
|
{file = "certifi-2019.11.28.tar.gz", hash = "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"},
|
||||||
@@ -580,10 +477,6 @@ immutables = [
|
|||||||
{file = "immutables-0.11-cp37-cp37m-win_amd64.whl", hash = "sha256:6b6d8d035e5888baad3db61dfb167476838a63afccecd927c365f228bb55754c"},
|
{file = "immutables-0.11-cp37-cp37m-win_amd64.whl", hash = "sha256:6b6d8d035e5888baad3db61dfb167476838a63afccecd927c365f228bb55754c"},
|
||||||
{file = "immutables-0.11.tar.gz", hash = "sha256:d6850578a0dc6530ac19113cfe4ddc13903df635212d498f176fe601a8a5a4a3"},
|
{file = "immutables-0.11.tar.gz", hash = "sha256:d6850578a0dc6530ac19113cfe4ddc13903df635212d498f176fe601a8a5a4a3"},
|
||||||
]
|
]
|
||||||
importlib-metadata = [
|
|
||||||
{file = "importlib_metadata-1.3.0-py2.py3-none-any.whl", hash = "sha256:d95141fbfa7ef2ec65cfd945e2af7e5a6ddbd7c8d9a25e66ff3be8e3daf9f60f"},
|
|
||||||
{file = "importlib_metadata-1.3.0.tar.gz", hash = "sha256:073a852570f92da5f744a3472af1b61e28e9f78ccf0c9117658dc32b15de7b45"},
|
|
||||||
]
|
|
||||||
itsdangerous = [
|
itsdangerous = [
|
||||||
{file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"},
|
{file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"},
|
||||||
{file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"},
|
{file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"},
|
||||||
@@ -595,10 +488,6 @@ jinja2 = [
|
|||||||
jsonpath = [
|
jsonpath = [
|
||||||
{file = "jsonpath-0.82.tar.gz", hash = "sha256:46d3fd2016cd5b842283d547877a02c418a0fe9aa7a6b0ae344115a2c990fef4"},
|
{file = "jsonpath-0.82.tar.gz", hash = "sha256:46d3fd2016cd5b842283d547877a02c418a0fe9aa7a6b0ae344115a2c990fef4"},
|
||||||
]
|
]
|
||||||
jsonschema = [
|
|
||||||
{file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"},
|
|
||||||
{file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"},
|
|
||||||
]
|
|
||||||
loguru = [
|
loguru = [
|
||||||
{file = "loguru-0.4.1-py3-none-any.whl", hash = "sha256:074b3caa6748452c1e4f2b302093c94b65d5a4c5a4d7743636b4121e06437b0e"},
|
{file = "loguru-0.4.1-py3-none-any.whl", hash = "sha256:074b3caa6748452c1e4f2b302093c94b65d5a4c5a4d7743636b4121e06437b0e"},
|
||||||
{file = "loguru-0.4.1.tar.gz", hash = "sha256:a6101fd435ac89ba5205a105a26a6ede9e4ddbb4408a6e167852efca47806d11"},
|
{file = "loguru-0.4.1.tar.gz", hash = "sha256:a6101fd435ac89ba5205a105a26a6ede9e4ddbb4408a6e167852efca47806d11"},
|
||||||
@@ -633,11 +522,6 @@ markupsafe = [
|
|||||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
|
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
|
||||||
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
|
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
|
||||||
]
|
]
|
||||||
more-itertools = [
|
|
||||||
{file = "more-itertools-5.0.0.tar.gz", hash = "sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4"},
|
|
||||||
{file = "more_itertools-5.0.0-py2-none-any.whl", hash = "sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc"},
|
|
||||||
{file = "more_itertools-5.0.0-py3-none-any.whl", hash = "sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"},
|
|
||||||
]
|
|
||||||
pydantic = [
|
pydantic = [
|
||||||
{file = "pydantic-1.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:07911aab70f3bc52bb845ce1748569c5e70478ac977e106a150dd9d0465ebf04"},
|
{file = "pydantic-1.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:07911aab70f3bc52bb845ce1748569c5e70478ac977e106a150dd9d0465ebf04"},
|
||||||
{file = "pydantic-1.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:012c422859bac2e03ab3151ea6624fecf0e249486be7eb8c6ee69c91740c6752"},
|
{file = "pydantic-1.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:012c422859bac2e03ab3151ea6624fecf0e249486be7eb8c6ee69c91740c6752"},
|
||||||
@@ -654,9 +538,6 @@ pydantic = [
|
|||||||
{file = "pydantic-1.4-py36.py37.py38-none-any.whl", hash = "sha256:72184c1421103cca128300120f8f1185fb42a9ea73a1c9845b1c53db8c026a7d"},
|
{file = "pydantic-1.4-py36.py37.py38-none-any.whl", hash = "sha256:72184c1421103cca128300120f8f1185fb42a9ea73a1c9845b1c53db8c026a7d"},
|
||||||
{file = "pydantic-1.4.tar.gz", hash = "sha256:f17ec336e64d4583311249fb179528e9a2c27c8a2eaf590ec6ec2c6dece7cb3f"},
|
{file = "pydantic-1.4.tar.gz", hash = "sha256:f17ec336e64d4583311249fb179528e9a2c27c8a2eaf590ec6ec2c6dece7cb3f"},
|
||||||
]
|
]
|
||||||
pyrsistent = [
|
|
||||||
{file = "pyrsistent-0.15.6.tar.gz", hash = "sha256:f3b280d030afb652f79d67c5586157c5c1355c9a58dfc7940566e28d28f3df1b"},
|
|
||||||
]
|
|
||||||
pyyaml = [
|
pyyaml = [
|
||||||
{file = "PyYAML-5.2-cp27-cp27m-win32.whl", hash = "sha256:35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc"},
|
{file = "PyYAML-5.2-cp27-cp27m-win32.whl", hash = "sha256:35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc"},
|
||||||
{file = "PyYAML-5.2-cp27-cp27m-win_amd64.whl", hash = "sha256:ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4"},
|
{file = "PyYAML-5.2-cp27-cp27m-win_amd64.whl", hash = "sha256:ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4"},
|
||||||
@@ -678,10 +559,6 @@ requests-toolbelt = [
|
|||||||
{file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"},
|
{file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"},
|
||||||
{file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"},
|
{file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"},
|
||||||
]
|
]
|
||||||
six = [
|
|
||||||
{file = "six-1.13.0-py2.py3-none-any.whl", hash = "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd"},
|
|
||||||
{file = "six-1.13.0.tar.gz", hash = "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"},
|
|
||||||
]
|
|
||||||
starlette = [
|
starlette = [
|
||||||
{file = "starlette-0.12.9.tar.gz", hash = "sha256:c2ac9a42e0e0328ad20fe444115ac5e3760c1ee2ac1ff8cdb5ec915c4a453411"},
|
{file = "starlette-0.12.9.tar.gz", hash = "sha256:c2ac9a42e0e0328ad20fe444115ac5e3760c1ee2ac1ff8cdb5ec915c4a453411"},
|
||||||
]
|
]
|
||||||
@@ -725,7 +602,3 @@ win32-setctime = [
|
|||||||
{file = "win32_setctime-1.0.1-py3-none-any.whl", hash = "sha256:568fd636c68350bcc54755213fe01966fe0a6c90b386c0776425944a0382abef"},
|
{file = "win32_setctime-1.0.1-py3-none-any.whl", hash = "sha256:568fd636c68350bcc54755213fe01966fe0a6c90b386c0776425944a0382abef"},
|
||||||
{file = "win32_setctime-1.0.1.tar.gz", hash = "sha256:b47e5023ec7f0b4962950902b15bc56464a380d869f59d27dbf9ab423b23e8f9"},
|
{file = "win32_setctime-1.0.1.tar.gz", hash = "sha256:b47e5023ec7f0b4962950902b15bc56464a380d869f59d27dbf9ab423b23e8f9"},
|
||||||
]
|
]
|
||||||
zipp = [
|
|
||||||
{file = "zipp-0.6.0-py2.py3-none-any.whl", hash = "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"},
|
|
||||||
{file = "zipp-0.6.0.tar.gz", hash = "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e"},
|
|
||||||
]
|
|
||||||
|
|||||||
+1
-2
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "httprunner"
|
name = "httprunner"
|
||||||
version = "3.0.1"
|
version = "3.0.2"
|
||||||
description = "One-stop solution for HTTP(S) testing."
|
description = "One-stop solution for HTTP(S) testing."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@@ -36,7 +36,6 @@ jinja2 = "^2.10.3"
|
|||||||
har2case = "^0.3.1"
|
har2case = "^0.3.1"
|
||||||
filetype = "^1.0.5"
|
filetype = "^1.0.5"
|
||||||
jsonpath = "^0.82"
|
jsonpath = "^0.82"
|
||||||
jsonschema = "^3.2.0"
|
|
||||||
pydantic = "^1.4"
|
pydantic = "^1.4"
|
||||||
loguru = "^0.4.1"
|
loguru = "^0.4.1"
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,9 @@
|
|||||||
"os_platform": "ios",
|
"os_platform": "ios",
|
||||||
"user_agent": "iOS/10.3"
|
"user_agent": "iOS/10.3"
|
||||||
},
|
},
|
||||||
"extract": [
|
"extract": {
|
||||||
{"session_token": "content.token"}
|
"session_token": "content.token"
|
||||||
],
|
},
|
||||||
"validate": [
|
"validate": [
|
||||||
{"eq": ["status_code", 200]},
|
{"eq": ["status_code", 200]},
|
||||||
{"len_eq": ["content.token", 16]}
|
{"len_eq": ["content.token", 16]}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ teststeps:
|
|||||||
os_platform: 'ios'
|
os_platform: 'ios'
|
||||||
app_version: '2.8.6'
|
app_version: '2.8.6'
|
||||||
extract:
|
extract:
|
||||||
- session_token: content.token
|
session_token: content.token
|
||||||
validate:
|
validate:
|
||||||
- eq: ["status_code", 200]
|
- eq: ["status_code", 200]
|
||||||
- len_eq: ["content.token", 16]
|
- len_eq: ["content.token", 16]
|
||||||
|
|||||||
Reference in New Issue
Block a user