mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-30 12:59:39 +08:00
change: replace jsonschema validation with pydantic
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
__version__ = "3.0.1"
|
||||
__version__ = "3.0.2"
|
||||
__description__ = "One-stop solution for HTTP(S) testing."
|
||||
|
||||
__all__ = ["__version__", "__description__"]
|
||||
|
||||
@@ -277,7 +277,7 @@ def load_test_file(path: str) -> dict:
|
||||
loaded_content["type"] = "testsuite"
|
||||
|
||||
elif "teststeps" in raw_content:
|
||||
# file_type: testcase (format version 2)
|
||||
# file_type: testcase
|
||||
loaded_content = load_testcase(raw_content)
|
||||
loaded_content["path"] = path
|
||||
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
|
||||
project_mapping["PWD"] = project_working_directory
|
||||
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
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -1,70 +1,43 @@
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
|
||||
import jsonschema
|
||||
from loguru import logger
|
||||
from pydantic import ValidationError
|
||||
|
||||
from httprunner import exceptions
|
||||
|
||||
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)
|
||||
from httprunner.schema import Api, TestCase, TestSuite
|
||||
|
||||
|
||||
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
|
||||
def validate_api_format(content):
|
||||
""" 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
|
||||
def validate_testcase_format(content):
|
||||
""" 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
|
||||
def validate_testsuite_format(content):
|
||||
""" 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):
|
||||
|
||||
@@ -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 .testsuite import TestSuite
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from httprunner.schema import common
|
||||
|
||||
@@ -7,8 +7,8 @@ class Api(BaseModel):
|
||||
name: common.Name
|
||||
request: common.Request
|
||||
variables: common.Variables
|
||||
base_url: common.BaseUrl
|
||||
setup_hooks: common.Hook
|
||||
teardown_hooks: common.Hook
|
||||
extract: common.Extract
|
||||
validate: common.Validate
|
||||
base_url: common.BaseUrl = ""
|
||||
setup_hooks: common.Hook = []
|
||||
teardown_hooks: common.Hook = []
|
||||
extract: common.Extract = {}
|
||||
validation: common.Validate = Field([], alias="validate")
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from enum import Enum
|
||||
from typing import Dict, List, Any, Tuple
|
||||
from typing import Dict, List, Any
|
||||
|
||||
from pydantic import BaseModel, HttpUrl, Field
|
||||
|
||||
Name = str
|
||||
Url = HttpUrl
|
||||
BaseUrl = str
|
||||
Url = str
|
||||
BaseUrl = HttpUrl
|
||||
Variables = Dict[str, Any]
|
||||
Headers = Dict[str, str]
|
||||
Verify = bool
|
||||
|
||||
@@ -13,7 +13,8 @@ class ProjectMeta(BaseModel):
|
||||
|
||||
class TestStep(BaseModel):
|
||||
name: common.Name
|
||||
request: common.Request
|
||||
api: str = None # TODO: replace with FilePath
|
||||
request: common.Request = None
|
||||
extract: Dict[str, str] = {}
|
||||
validation: common.Validate = Field([], alias="validate")
|
||||
|
||||
|
||||
10
httprunner/schema/testsuite.py
Normal file
10
httprunner/schema/testsuite.py
Normal file
@@ -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]
|
||||
Reference in New Issue
Block a user