feat: use pydantic to implement testcase schema

This commit is contained in:
debugtalk
2020-02-29 23:26:54 +08:00
parent 25b2fcd0f5
commit 95cb547184
9 changed files with 165 additions and 66 deletions

View File

@@ -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)

View File

@@ -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()

View File

@@ -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

View File

@@ -0,0 +1 @@
from .testcase import ProjectMeta, TestCase, TestCases

14
httprunner/schema/api.py Normal file
View 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

View 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

View 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]

View File

@@ -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
View File