mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-12 02:21:29 +08:00
feat: use pydantic to implement testcase schema
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from fastapi import FastAPI
|
||||
|
||||
from httprunner import __version__
|
||||
from .routers import deps, debugtalk, testcase
|
||||
from .routers import deps, debugtalk, debug
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@@ -19,4 +19,4 @@ async def get_hrun_version():
|
||||
|
||||
app.include_router(deps.router)
|
||||
app.include_router(debugtalk.router)
|
||||
app.include_router(testcase.router)
|
||||
app.include_router(debug.router)
|
||||
|
||||
@@ -19,7 +19,7 @@ def stdout_io(stdout=None):
|
||||
sys.stdout = old
|
||||
|
||||
|
||||
@router.post("/hrun/debug/debugtalk", tags=["debugtalk"])
|
||||
@router.post("/hrun/debug/debugtalk_py", tags=["debugtalk"])
|
||||
async def debug_python(request: Request):
|
||||
body = await request.body()
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from httprunner.api import HttpRunner
|
||||
|
||||
router = APIRouter()
|
||||
runner = HttpRunner()
|
||||
|
||||
|
||||
@router.get("/hrun/debug/api", tags=["testcase"])
|
||||
async def debug_single_api():
|
||||
pass
|
||||
|
||||
|
||||
@router.get("/hrun/debug/testcase", tags=["testcase"])
|
||||
async def debug_single_testcase():
|
||||
resp = {
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"result": {}
|
||||
}
|
||||
testcases = [
|
||||
{
|
||||
"config": {
|
||||
'name': "post data",
|
||||
'variables': {
|
||||
"var1": "abc",
|
||||
"var2": "def"
|
||||
},
|
||||
"export": ["status_code", "req_data"]
|
||||
},
|
||||
"teststeps": [
|
||||
{
|
||||
"name": "post data",
|
||||
"request": {
|
||||
"url": "http://httpbin.org/post",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"User-Agent": "python-requests/2.18.4",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
"data": "$var1"
|
||||
},
|
||||
"extract": {
|
||||
"status_code": "status_code",
|
||||
"req_data": "content.data"
|
||||
},
|
||||
"validate": [
|
||||
{"eq": ["status_code", 201]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
tests_mapping = {
|
||||
"testcases": testcases
|
||||
}
|
||||
summary = runner.run_tests(tests_mapping)
|
||||
if not summary["success"]:
|
||||
resp["code"] = 1
|
||||
resp["message"] = "fail"
|
||||
|
||||
resp["result"] = summary
|
||||
return resp
|
||||
1
httprunner/schema/__init__.py
Normal file
1
httprunner/schema/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .testcase import ProjectMeta, TestCase, TestCases
|
||||
14
httprunner/schema/api.py
Normal file
14
httprunner/schema/api.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
from httprunner.schema import common
|
||||
|
||||
|
||||
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
|
||||
61
httprunner/schema/common.py
Normal file
61
httprunner/schema/common.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from enum import Enum
|
||||
from typing import Dict, List, Any, Tuple
|
||||
|
||||
from pydantic import BaseModel, HttpUrl, Field
|
||||
|
||||
Name = str
|
||||
Url = HttpUrl
|
||||
BaseUrl = str
|
||||
Variables = Dict[str, Any]
|
||||
Headers = Dict[str, str]
|
||||
Verify = bool
|
||||
Hook = List[str]
|
||||
Export = List[str]
|
||||
Extract = Dict[str, str]
|
||||
Validate = List[Dict[str, Tuple[str, Any]]]
|
||||
Env = Dict[str, Any]
|
||||
|
||||
|
||||
class MethodEnum(str, Enum):
|
||||
GET = 'GET'
|
||||
POST = 'POST'
|
||||
PUT = "PUT"
|
||||
DELETE = "DELETE"
|
||||
HEAD = "HEAD"
|
||||
OPTIONS = "OPTIONS"
|
||||
PATCH = "PATCH"
|
||||
CONNECT = "CONNECT"
|
||||
TRACE = "TRACE"
|
||||
|
||||
|
||||
class TestsConfig(BaseModel):
|
||||
name: Name
|
||||
verify: Verify = False
|
||||
base_url: BaseUrl = ""
|
||||
variables: Variables = {}
|
||||
setup_hooks: Hook = []
|
||||
teardown_hooks: Hook = []
|
||||
export: Export = []
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"examples": [
|
||||
{
|
||||
"name": "used in testcase/testsuite to configure common fields",
|
||||
"verify": False,
|
||||
"base_url": "https://httpbin.org"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
class Request(BaseModel):
|
||||
method: MethodEnum = MethodEnum.GET
|
||||
url: Url
|
||||
params: Dict[str, str] = {}
|
||||
headers: Headers = {}
|
||||
req_json: Dict = Field({}, alias="json")
|
||||
cookies: Dict[str, str] = {}
|
||||
timeout: int = 120
|
||||
allow_redirects: bool = True
|
||||
verify: Verify = False
|
||||
85
httprunner/schema/testcase.py
Normal file
85
httprunner/schema/testcase.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from typing import Dict, List, Text
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from httprunner.schema import common
|
||||
|
||||
|
||||
class ProjectMeta(BaseModel):
|
||||
debugtalk_py: Text = ""
|
||||
variables: common.Variables = {}
|
||||
env: common.Env = {}
|
||||
|
||||
|
||||
class TestStep(BaseModel):
|
||||
name: common.Name
|
||||
request: common.Request
|
||||
extract: Dict[str, str] = {}
|
||||
validation: common.Validate = Field([], alias="validate")
|
||||
|
||||
|
||||
class TestCase(BaseModel):
|
||||
config: common.TestsConfig
|
||||
teststeps: List[TestStep]
|
||||
|
||||
class Config:
|
||||
schema_extra = {
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
TestCases = List[TestCase]
|
||||
@@ -40,6 +40,7 @@ filetype = "^1.0.5"
|
||||
jsonpath = "^0.82"
|
||||
sentry-sdk = "^0.13.5"
|
||||
jsonschema = "^3.2.0"
|
||||
pydantic = "^1.4"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
flask = "<1.0.0"
|
||||
|
||||
0
tests/test_schema.py
Normal file
0
tests/test_schema.py
Normal file
Reference in New Issue
Block a user