Deployed e5fdf96 with MkDocs version: 1.0.4

This commit is contained in:
debugtalk
2019-11-01 23:17:45 +08:00
commit 9185128d87
136 changed files with 26949 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
username,password,phone
test1,111111,18600000001
test2,222222,18600000002
test3,333333,18600000003
1 username password phone
2 test1 111111 18600000001
3 test2 222222 18600000002
4 test3 333333 18600000003
+223
View File
@@ -0,0 +1,223 @@
import hashlib
import hmac
import json
import random
import string
from functools import wraps
from flask import Flask, make_response, request
SECRET_KEY = "DebugTalk"
app = Flask(__name__)
""" storage all users' data
data structure:
users_dict = {
'uid1': {
'name': 'name1',
'password': 'pwd1'
},
'uid2': {
'name': 'name2',
'password': 'pwd2'
}
}
"""
users_dict = {}
""" storage all token data
data structure:
token_dict = {
'device_sn1': 'token1',
'device_sn2': 'token1'
}
"""
token_dict = {}
def gen_random_string(str_len):
""" generate random string with specified length
"""
return ''.join(
random.choice(string.ascii_letters + string.digits) for _ in range(str_len))
def get_sign(*args):
content = ''.join(args).encode('ascii')
sign_key = SECRET_KEY.encode('ascii')
sign = hmac.new(sign_key, content, hashlib.sha1).hexdigest()
return sign
def gen_md5(*args):
return hashlib.md5("".join(args).encode('utf-8')).hexdigest()
def validate_request(func):
@wraps(func)
def wrapper(*args, **kwargs):
device_sn = request.headers.get('device_sn', "")
token = request.headers.get('token', "")
if not device_sn or not token:
result = {
'success': False,
'msg': "device_sn or token is null."
}
response = make_response(json.dumps(result), 401)
response.headers["Content-Type"] = "application/json"
return response
if token_dict.get(device_sn) != token:
result = {
'success': False,
'msg': "Authorization failed!"
}
response = make_response(json.dumps(result), 403)
response.headers["Content-Type"] = "application/json"
return response
return func(*args, **kwargs)
return wrapper
@app.route('/')
def index():
return "Hello World!"
@app.route('/api/get-token', methods=['POST'])
def get_token():
device_sn = request.headers.get('device_sn', "")
os_platform = request.headers.get('os_platform', "")
app_version = request.headers.get('app_version', "")
data = request.get_json()
sign = data.get('sign', "")
expected_sign = get_sign(device_sn, os_platform, app_version)
if expected_sign != sign:
result = {
'success': False,
'msg': "Authorization failed!"
}
response = make_response(json.dumps(result), 403)
else:
token = gen_random_string(16)
token_dict[device_sn] = token
result = {
'success': True,
'token': token
}
response = make_response(json.dumps(result))
response.headers["Content-Type"] = "application/json"
return response
@app.route('/api/users')
@validate_request
def get_users():
users_list = [user for uid, user in users_dict.items()]
users = {
'success': True,
'count': len(users_list),
'items': users_list
}
response = make_response(json.dumps(users))
response.headers["Content-Type"] = "application/json"
return response
@app.route('/api/reset-all')
@validate_request
def clear_users():
users_dict.clear()
result = {
'success': True
}
response = make_response(json.dumps(result))
response.headers["Content-Type"] = "application/json"
return response
@app.route('/api/users/<int:uid>', methods=['POST'])
@validate_request
def create_user(uid):
user = request.get_json()
if uid not in users_dict:
result = {
'success': True,
'msg': "user created successfully."
}
status_code = 201
users_dict[uid] = user
else:
result = {
'success': False,
'msg': "user already existed."
}
status_code = 500
response = make_response(json.dumps(result), status_code)
response.headers["Content-Type"] = "application/json"
return response
@app.route('/api/users/<int:uid>')
@validate_request
def get_user(uid):
user = users_dict.get(uid, {})
if user:
result = {
'success': True,
'data': user
}
status_code = 200
else:
result = {
'success': False,
'data': user
}
status_code = 404
response = make_response(json.dumps(result), status_code)
response.headers["Content-Type"] = "application/json"
return response
@app.route('/api/users/<int:uid>', methods=['PUT'])
@validate_request
def update_user(uid):
user = users_dict.get(uid, {})
if user:
user = request.get_json()
success = True
status_code = 200
users_dict[uid] = user
else:
success = False
status_code = 404
result = {
'success': success,
'data': user
}
response = make_response(json.dumps(result), status_code)
response.headers["Content-Type"] = "application/json"
return response
@app.route('/api/users/<int:uid>', methods=['DELETE'])
@validate_request
def delete_user(uid):
user = users_dict.pop(uid, {})
if user:
success = True
status_code = 200
else:
success = False
status_code = 404
result = {
'success': success,
'data': user
}
response = make_response(json.dumps(result), status_code)
response.headers["Content-Type"] = "application/json"
return response
+3
View File
@@ -0,0 +1,3 @@
app_version
2.8.5
2.8.6
1 app_version
2 2.8.5
3 2.8.6
+48
View File
@@ -0,0 +1,48 @@
import hashlib
import hmac
import random
import string
import time
SECRET_KEY = "DebugTalk"
def gen_random_string(str_len):
random_char_list = []
for _ in range(str_len):
random_char = random.choice(string.ascii_letters + string.digits)
random_char_list.append(random_char)
random_string = ''.join(random_char_list)
return random_string
def get_sign(*args):
content = ''.join(args).encode('ascii')
sign_key = SECRET_KEY.encode('ascii')
sign = hmac.new(sign_key, content, hashlib.sha1).hexdigest()
return sign
def gen_user_id():
return int(time.time() * 1000)
def get_user_id():
return [
{"user_id": 1001},
{"user_id": 1002},
{"user_id": 1003},
{"user_id": 1004}
]
def get_account(num):
accounts = []
for index in range(1, num+1):
accounts.append(
{"username": "user%s" % index, "password": str(index) * 6},
)
return accounts
def get_os_platform():
return [
{"os_platform": "ios"},
{"os_platform": "android"}
]
+10
View File
@@ -0,0 +1,10 @@
config:
name: get token with parameters
testcases:
get token with $user_agent, $app_version, $os_platform:
testcase: demo-testcase-get-token.yml
parameters:
user_agent: ["iOS/10.1", "iOS/10.2", "iOS/10.3"]
app_version: ${P(app_version.csv)}
os_platform: ${get_os_platform()}
+58
View File
@@ -0,0 +1,58 @@
[
{
"config": {
"name": "testcase description",
"variables": {}
}
},
{
"test": {
"name": "/api/get-token",
"request": {
"url": "http://127.0.0.1:5000/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"os_platform": "ios",
"app_version": "2.8.6",
"Content-Type": "application/json"
},
"json": {
"sign": "9c0c7e51c91ae963c833a4ccbab8d683c4a90c98"
}
},
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]},
{"eq": ["content.token", "baNLX1zhFYP11Seb"]}
]
}
},
{
"test": {
"name": "/api/users/1000",
"request": {
"url": "http://127.0.0.1:5000/api/users/1000",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"token": "baNLX1zhFYP11Seb",
"Content-Type": "application/json"
},
"json": {
"name": "user1",
"password": "123456"
}
},
"validate": [
{"eq": ["status_code", 201]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]},
{"eq": ["content.msg", "user created successfully."]}
]
}
}
]
+41
View File
@@ -0,0 +1,41 @@
- config:
name: testcase description
variables: {}
- test:
name: /api/get-token
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: 2.8.6
device_sn: FwgRiO7CNA50DSU
os_platform: ios
json:
sign: 9c0c7e51c91ae963c833a4ccbab8d683c4a90c98
method: POST
url: http://127.0.0.1:5000/api/get-token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- eq: [content.token, baNLX1zhFYP11Seb]
- test:
name: /api/users/1000
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
device_sn: FwgRiO7CNA50DSU
token: baNLX1zhFYP11Seb
json:
name: user1
password: '123456'
method: POST
url: http://127.0.0.1:5000/api/users/1000
validate:
- eq: [status_code, 201]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- eq: [content.msg, user created successfully.]
+57
View File
@@ -0,0 +1,57 @@
[
{
"config": {
"name": "testcase description",
"variables": {}
}
},
{
"test": {
"name": "/api/get-token",
"request": {
"url": "http://127.0.0.1:5000/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"os_platform": "ios",
"app_version": "2.8.6",
"Content-Type": "application/json"
},
"json": {
"sign": "9c0c7e51c91ae963c833a4ccbab8d683c4a90c98"
}
},
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]}
]
}
},
{
"test": {
"name": "/api/users/1000",
"request": {
"url": "http://127.0.0.1:5000/api/users/1000",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"token": "baNLX1zhFYP11Seb",
"Content-Type": "application/json"
},
"json": {
"name": "user1",
"password": "123456"
}
},
"validate": [
{"eq": ["status_code", 201]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]},
{"eq": ["content.msg", "user created successfully."]}
]
}
}
]
+40
View File
@@ -0,0 +1,40 @@
- config:
name: testcase description
variables: {}
- test:
name: /api/get-token
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: 2.8.6
device_sn: FwgRiO7CNA50DSU
os_platform: ios
json:
sign: 9c0c7e51c91ae963c833a4ccbab8d683c4a90c98
method: POST
url: http://127.0.0.1:5000/api/get-token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- test:
name: /api/users/1000
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
device_sn: FwgRiO7CNA50DSU
token: baNLX1zhFYP11Seb
json:
name: user1
password: '123456'
method: POST
url: http://127.0.0.1:5000/api/users/1000
validate:
- eq: [status_code, 201]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- eq: [content.msg, user created successfully.]
+60
View File
@@ -0,0 +1,60 @@
[
{
"config": {
"name": "testcase description",
"variables": {}
}
},
{
"test": {
"name": "/api/get-token",
"request": {
"url": "http://127.0.0.1:5000/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"os_platform": "ios",
"app_version": "2.8.6",
"Content-Type": "application/json"
},
"json": {
"sign": "9c0c7e51c91ae963c833a4ccbab8d683c4a90c98"
}
},
"extract": [
{"token": "content.token"}
],
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]}
]
}
},
{
"test": {
"name": "/api/users/1000",
"request": {
"url": "http://127.0.0.1:5000/api/users/1000",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"token": "$token",
"Content-Type": "application/json"
},
"json": {
"name": "user1",
"password": "123456"
}
},
"validate": [
{"eq": ["status_code", 201]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]},
{"eq": ["content.msg", "user created successfully."]}
]
}
}
]
+42
View File
@@ -0,0 +1,42 @@
- config:
name: testcase description
variables: {}
- test:
name: /api/get-token
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: 2.8.6
device_sn: FwgRiO7CNA50DSU
os_platform: ios
json:
sign: 9c0c7e51c91ae963c833a4ccbab8d683c4a90c98
method: POST
url: http://127.0.0.1:5000/api/get-token
extract:
token: content.token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- test:
name: /api/users/1000
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
device_sn: FwgRiO7CNA50DSU
token: $token
json:
name: user1
password: '123456'
method: POST
url: http://127.0.0.1:5000/api/users/1000
validate:
- eq: [status_code, 201]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- eq: [content.msg, user created successfully.]
+61
View File
@@ -0,0 +1,61 @@
[
{
"config": {
"name": "testcase description",
"base_url": "http://127.0.0.1:5000",
"variables": {}
}
},
{
"test": {
"name": "/api/get-token",
"request": {
"url": "/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"os_platform": "ios",
"app_version": "2.8.6",
"Content-Type": "application/json"
},
"json": {
"sign": "9c0c7e51c91ae963c833a4ccbab8d683c4a90c98"
}
},
"extract": [
{"token": "content.token"}
],
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]}
]
}
},
{
"test": {
"name": "/api/users/1000",
"request": {
"url": "/api/users/1000",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"token": "$token",
"Content-Type": "application/json"
},
"json": {
"name": "user1",
"password": "123456"
}
},
"validate": [
{"eq": ["status_code", 201]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]},
{"eq": ["content.msg", "user created successfully."]}
]
}
}
]
+43
View File
@@ -0,0 +1,43 @@
- config:
name: testcase description
base_url: http://127.0.0.1:5000
variables: {}
- test:
name: /api/get-token
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: 2.8.6
device_sn: FwgRiO7CNA50DSU
os_platform: ios
json:
sign: 9c0c7e51c91ae963c833a4ccbab8d683c4a90c98
method: POST
url: /api/get-token
extract:
token: content.token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- test:
name: /api/users/1000
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
device_sn: FwgRiO7CNA50DSU
token: $token
json:
name: user1
password: '123456'
method: POST
url: /api/users/1000
validate:
- eq: [status_code, 201]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- eq: [content.msg, user created successfully.]
+70
View File
@@ -0,0 +1,70 @@
[
{
"config": {
"name": "testcase description",
"base_url": "http://127.0.0.1:5000",
"variables": {}
}
},
{
"test": {
"name": "/api/get-token",
"variables": {
"device_sn": "FwgRiO7CNA50DSU",
"os_platform": "ios",
"app_version": "2.8.6"
},
"request": {
"url": "/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "$device_sn",
"os_platform": "$os_platform",
"app_version": "$app_version",
"Content-Type": "application/json"
},
"json": {
"sign": "9c0c7e51c91ae963c833a4ccbab8d683c4a90c98"
}
},
"extract": [
{"token": "content.token"}
],
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]}
]
}
},
{
"test": {
"name": "/api/users/$user_id",
"variables": {
"device_sn": "FwgRiO7CNA50DSU",
"user_id": "1000"
},
"request": {
"url": "/api/users/$user_id",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "$device_sn",
"token": "$token",
"Content-Type": "application/json"
},
"json": {
"name": "user1",
"password": "123456"
}
},
"validate": [
{"eq": ["status_code", 201]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]},
{"eq": ["content.msg", "user created successfully."]}
]
}
}
]
+50
View File
@@ -0,0 +1,50 @@
- config:
name: testcase description
base_url: http://127.0.0.1:5000
variables: {}
- test:
name: /api/get-token
variables:
app_version: 2.8.6
device_sn: FwgRiO7CNA50DSU
os_platform: ios
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: $app_version
device_sn: $device_sn
os_platform: $os_platform
json:
sign: 9c0c7e51c91ae963c833a4ccbab8d683c4a90c98
method: POST
url: /api/get-token
extract:
token: content.token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- test:
name: /api/users/$user_id
variables:
device_sn: FwgRiO7CNA50DSU
user_id: 1000
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
device_sn: $device_sn
token: $token
json:
name: user1
password: '123456'
method: POST
url: /api/users/$user_id
validate:
- eq: [status_code, 201]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- eq: [content.msg, user created successfully.]
+70
View File
@@ -0,0 +1,70 @@
[
{
"config": {
"name": "testcase description",
"base_url": "http://127.0.0.1:5000",
"variables": {
"device_sn": "FwgRiO7CNA50DSU"
}
}
},
{
"test": {
"name": "/api/get-token",
"variables": {
"os_platform": "ios",
"app_version": "2.8.6"
},
"request": {
"url": "/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "$device_sn",
"os_platform": "$os_platform",
"app_version": "$app_version",
"Content-Type": "application/json"
},
"json": {
"sign": "9c0c7e51c91ae963c833a4ccbab8d683c4a90c98"
}
},
"extract": [
{"token": "content.token"}
],
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]}
]
}
},
{
"test": {
"name": "/api/users/$user_id",
"variables": {
"user_id": "1000"
},
"request": {
"url": "/api/users/$user_id",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "$device_sn",
"token": "$token",
"Content-Type": "application/json"
},
"json": {
"name": "user1",
"password": "123456"
}
},
"validate": [
{"eq": ["status_code", 201]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]},
{"eq": ["content.msg", "user created successfully."]}
]
}
}
]
+49
View File
@@ -0,0 +1,49 @@
- config:
name: testcase description
base_url: http://127.0.0.1:5000
variables:
device_sn: FwgRiO7CNA50DSU
- test:
name: /api/get-token
variables:
app_version: 2.8.6
os_platform: ios
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: $app_version
device_sn: $device_sn
os_platform: $os_platform
json:
sign: 9c0c7e51c91ae963c833a4ccbab8d683c4a90c98
method: POST
url: /api/get-token
extract:
token: content.token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- test:
name: /api/users/$user_id
variables:
user_id: 1000
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
device_sn: $device_sn
token: $token
json:
name: user1
password: '123456'
method: POST
url: /api/users/$user_id
validate:
- eq: [status_code, 201]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- eq: [content.msg, user created successfully.]
+70
View File
@@ -0,0 +1,70 @@
[
{
"config": {
"name": "testcase description",
"base_url": "http://127.0.0.1:5000",
"variables": {
"device_sn": "${gen_random_string(15)}"
}
}
},
{
"test": {
"name": "/api/get-token",
"variables": {
"os_platform": "ios",
"app_version": "2.8.6"
},
"request": {
"url": "/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "$device_sn",
"os_platform": "$os_platform",
"app_version": "$app_version",
"Content-Type": "application/json"
},
"json": {
"sign": "${get_sign($device_sn, $os_platform, $app_version)}"
}
},
"extract": [
{"token": "content.token"}
],
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]}
]
}
},
{
"test": {
"name": "/api/users/$user_id",
"variables": {
"user_id": "${gen_user_id()}"
},
"request": {
"url": "/api/users/$user_id",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "$device_sn",
"token": "$token",
"Content-Type": "application/json"
},
"json": {
"name": "user1",
"password": "123456"
}
},
"validate": [
{"eq": ["status_code", 201]},
{"eq": ["headers.Content-Type", "application/json"]},
{"eq": ["content.success", true]},
{"eq": ["content.msg", "user created successfully."]}
]
}
}
]
+49
View File
@@ -0,0 +1,49 @@
- config:
name: testcase description
base_url: http://127.0.0.1:5000
variables:
device_sn: ${gen_random_string(15)}
- test:
name: /api/get-token
variables:
app_version: 2.8.6
os_platform: ios
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: $app_version
device_sn: $device_sn
os_platform: $os_platform
json:
sign: ${get_sign($device_sn, $os_platform, $app_version)}
method: POST
url: /api/get-token
extract:
token: content.token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- test:
name: /api/users/$user_id
variables:
user_id: ${gen_user_id()}
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
device_sn: $device_sn
token: $token
json:
name: user1
password: '123456'
method: POST
url: /api/users/$user_id
validate:
- eq: [status_code, 201]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
- eq: [content.msg, user created successfully.]
+13
View File
@@ -0,0 +1,13 @@
{
"config": {
"name": "create users with parameters"
},
"testcases": {
"create user $user_id": {
"testcase": "demo-quickstart-6.yml",
"parameters": {
"user_id": [1001, 1002, 1003, 1004]
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
config:
name: testcase description
testcases:
create user $user_id:
testcase: demo-quickstart-6.yml
parameters:
user_id: [1001, 1002, 1003, 1004]
+221
View File
@@ -0,0 +1,221 @@
{
"log": {
"version": "1.2",
"creator": {
"name": "Charles Proxy",
"version": "4.2.1"
},
"entries": [
{
"startedDateTime": "2018-02-19T17:30:00.904+08:00",
"time": 3,
"request": {
"method": "POST",
"url": "http://127.0.0.1:5000/api/get-token",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
{
"name": "Host",
"value": "127.0.0.1:5000"
},
{
"name": "User-Agent",
"value": "python-requests/2.18.4"
},
{
"name": "Accept-Encoding",
"value": "gzip, deflate"
},
{
"name": "Accept",
"value": "*/*"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "device_sn",
"value": "FwgRiO7CNA50DSU"
},
{
"name": "os_platform",
"value": "ios"
},
{
"name": "app_version",
"value": "2.8.6"
},
{
"name": "Content-Length",
"value": "52"
},
{
"name": "Content-Type",
"value": "application/json"
}
],
"queryString": [],
"postData": {
"mimeType": "application/json",
"text": "{\"sign\": \"9c0c7e51c91ae963c833a4ccbab8d683c4a90c98\"}"
},
"headersSize": 299,
"bodySize": 52
},
"response": {
"_charlesStatus": "COMPLETE",
"status": 200,
"statusText": "OK",
"httpVersion": "HTTP/1.0",
"cookies": [],
"headers": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Content-Length",
"value": "46"
},
{
"name": "Server",
"value": "Werkzeug/0.14.1 Python/3.6.4"
},
{
"name": "Date",
"value": "Mon, 19 Feb 2018 09:30:00 GMT"
},
{
"name": "Proxy-Connection",
"value": "Close"
}
],
"content": {
"size": 46,
"mimeType": "application/json",
"text": "eyJzdWNjZXNzIjogdHJ1ZSwgInRva2VuIjogImJhTkxYMXpoRllQMTFTZWIifQ==",
"encoding": "base64"
},
"redirectURL": null,
"headersSize": 175,
"bodySize": 46
},
"serverIPAddress": "127.0.0.1",
"cache": {},
"timings": {
"dns": 1,
"connect": 0,
"ssl": -1,
"send": 0,
"wait": 1,
"receive": 1
}
},
{
"startedDateTime": "2018-02-19T17:30:00.911+08:00",
"time": 3,
"request": {
"method": "POST",
"url": "http://127.0.0.1:5000/api/users/1000",
"httpVersion": "HTTP/1.1",
"cookies": [],
"headers": [
{
"name": "Host",
"value": "127.0.0.1:5000"
},
{
"name": "User-Agent",
"value": "python-requests/2.18.4"
},
{
"name": "Accept-Encoding",
"value": "gzip, deflate"
},
{
"name": "Accept",
"value": "*/*"
},
{
"name": "Connection",
"value": "keep-alive"
},
{
"name": "device_sn",
"value": "FwgRiO7CNA50DSU"
},
{
"name": "token",
"value": "baNLX1zhFYP11Seb"
},
{
"name": "Content-Length",
"value": "39"
},
{
"name": "Content-Type",
"value": "application/json"
}
],
"queryString": [],
"postData": {
"mimeType": "application/json",
"text": "{\"name\": \"user1\", \"password\": \"123456\"}"
},
"headersSize": 265,
"bodySize": 39
},
"response": {
"_charlesStatus": "COMPLETE",
"status": 201,
"statusText": "CREATED",
"httpVersion": "HTTP/1.0",
"cookies": [],
"headers": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Content-Length",
"value": "54"
},
{
"name": "Server",
"value": "Werkzeug/0.14.1 Python/3.6.4"
},
{
"name": "Date",
"value": "Mon, 19 Feb 2018 09:30:00 GMT"
},
{
"name": "Proxy-Connection",
"value": "Close"
}
],
"content": {
"size": 54,
"mimeType": "application/json",
"text": "eyJzdWNjZXNzIjogdHJ1ZSwgIm1zZyI6ICJ1c2VyIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5LiJ9",
"encoding": "base64"
},
"redirectURL": null,
"headersSize": 77,
"bodySize": 54
},
"serverIPAddress": "127.0.0.1",
"cache": {},
"timings": {
"dns": 0,
"connect": 0,
"ssl": -1,
"send": 0,
"wait": 3,
"receive": 0
}
}
]
}
}
+98
View File
@@ -0,0 +1,98 @@
[
{
"config": {
"name": "testcase description",
"variables": {}
}
},
{
"test": {
"name": "/api/get-token",
"request": {
"url": "http://127.0.0.1:5000/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"os_platform": "ios",
"app_version": "2.8.6",
"Content-Type": "application/json"
},
"json": {
"sign": "9c0c7e51c91ae963c833a4ccbab8d683c4a90c98"
}
},
"validate": [
{
"eq": [
"status_code",
200
]
},
{
"eq": [
"headers.Content-Type",
"application/json"
]
},
{
"eq": [
"content.success",
true
]
},
{
"eq": [
"content.token",
"baNLX1zhFYP11Seb"
]
}
]
}
},
{
"test": {
"name": "/api/users/1000",
"request": {
"url": "http://127.0.0.1:5000/api/users/1000",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.18.4",
"device_sn": "FwgRiO7CNA50DSU",
"token": "baNLX1zhFYP11Seb",
"Content-Type": "application/json"
},
"json": {
"name": "user1",
"password": "123456"
}
},
"validate": [
{
"eq": [
"status_code",
201
]
},
{
"eq": [
"headers.Content-Type",
"application/json"
]
},
{
"eq": [
"content.success",
true
]
},
{
"eq": [
"content.msg",
"user created successfully."
]
}
]
}
}
]
+55
View File
@@ -0,0 +1,55 @@
- config:
name: testcase description
variables: {}
- test:
name: /api/get-token
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: 2.8.6
device_sn: FwgRiO7CNA50DSU
os_platform: ios
json:
sign: 9c0c7e51c91ae963c833a4ccbab8d683c4a90c98
method: POST
url: http://127.0.0.1:5000/api/get-token
validate:
- eq:
- status_code
- 200
- eq:
- headers.Content-Type
- application/json
- eq:
- content.success
- true
- eq:
- content.token
- baNLX1zhFYP11Seb
- test:
name: /api/users/1000
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
device_sn: FwgRiO7CNA50DSU
token: baNLX1zhFYP11Seb
json:
name: user1
password: '123456'
method: POST
url: http://127.0.0.1:5000/api/users/1000
validate:
- eq:
- status_code
- 201
- eq:
- headers.Content-Type
- application/json
- eq:
- content.success
- true
- eq:
- content.msg
- user created successfully.
+27
View File
@@ -0,0 +1,27 @@
- config:
name: get token
base_url: http://127.0.0.1:5000
variables:
device_sn: ${gen_random_string(15)}
os_platform: 'ios'
app_version: '2.8.6'
- test:
name: get token with $device_sn, $os_platform, $app_version
request:
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
app_version: $app_version
device_sn: $device_sn
os_platform: $os_platform
json:
sign: ${get_sign($device_sn, $os_platform, $app_version)}
method: POST
url: /api/get-token
extract:
token: content.token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
+34
View File
@@ -0,0 +1,34 @@
- config:
name: "user management testcase."
parameters:
- user_agent: ["iOS/10.1", "iOS/10.2", "iOS/10.3"]
- app_version: ${P(app_version.csv)}
- os_platform: ${get_os_platform()}
variables:
- user_agent: 'iOS/10.3'
- device_sn: ${gen_random_string(15)}
- os_platform: 'ios'
- app_version: '2.8.6'
request:
base_url: http://127.0.0.1:5000
headers:
Content-Type: application/json
device_sn: $device_sn
- test:
name: get token with $user_agent, $os_platform, $app_version
request:
url: /api/get-token
method: POST
headers:
app_version: $app_version
os_platform: $os_platform
user_agent: $user_agent
json:
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
extract:
- token: content.token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.success, true]
+115
View File
@@ -0,0 +1,115 @@
{
"project_mapping":{
"env":{},
"PWD":"/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner-docs-v2x/docs/data",
"debugtalk.py":"/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner-docs-v2x/docs/data/debugtalk.py",
"test_path":"docs/data/demo-quickstart-6.json"
},
"testcases":[
{
"config":{
"name":"testcase description",
"base_url":"http://127.0.0.1:5000",
"variables":{
"device_sn":"${gen_random_string(15)}"
}
},
"teststeps":[
{
"name":"/api/get-token",
"variables":{
"os_platform":"ios",
"app_version":"2.8.6"
},
"request":{
"url":"/api/get-token",
"method":"POST",
"headers":{
"User-Agent":"python-requests/2.18.4",
"device_sn":"$device_sn",
"os_platform":"$os_platform",
"app_version":"$app_version",
"Content-Type":"application/json"
},
"json":{
"sign":"${get_sign($device_sn, $os_platform, $app_version)}"
}
},
"extract":[
{
"token":"content.token"
}
],
"validate":[
{
"eq":[
"status_code",
200
]
},
{
"eq":[
"headers.Content-Type",
"application/json"
]
},
{
"eq":[
"content.success",
true
]
}
]
},
{
"name":"/api/users/$user_id",
"variables":{
"user_id":"${gen_user_id()}"
},
"request":{
"url":"/api/users/$user_id",
"method":"POST",
"headers":{
"User-Agent":"python-requests/2.18.4",
"device_sn":"$device_sn",
"token":"$token",
"Content-Type":"application/json"
},
"json":{
"name":"user1",
"password":"123456"
}
},
"validate":[
{
"eq":[
"status_code",
201
]
},
{
"eq":[
"headers.Content-Type",
"application/json"
]
},
{
"eq":[
"content.success",
true
]
},
{
"eq":[
"content.msg",
"user created successfully."
]
}
]
}
],
"path":"/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner-docs-v2x/docs/data/demo-quickstart-6.json",
"type":"testcase"
}
]
}
+115
View File
@@ -0,0 +1,115 @@
{
"project_mapping":{
"env":{},
"PWD":"/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner-docs-v2x/docs/data",
"debugtalk.py":"/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner-docs-v2x/docs/data/debugtalk.py",
"test_path":"docs/data/demo-quickstart-6.json"
},
"testcases":[
{
"config":{
"name":"testcase description"
},
"teststeps":[
{
"request":{
"url":"http://127.0.0.1:5000/api/get-token",
"method":"POST",
"headers":{
"User-Agent":"python-requests/2.18.4",
"device_sn":"$device_sn",
"os_platform":"$os_platform",
"app_version":"$app_version",
"Content-Type":"application/json"
},
"json":{
"sign":"${get_sign($device_sn, $os_platform, $app_version)}"
}
},
"extract":[
{
"token":"content.token"
}
],
"validate":[
{
"eq":[
"status_code",
200
]
},
{
"eq":[
"headers.Content-Type",
"application/json"
]
},
{
"eq":[
"content.success",
true
]
}
],
"verify":true,
"variables":{
"os_platform":"ios",
"app_version":"2.8.6",
"device_sn":"mmHBimjzK4Pk6mg"
},
"name":"/api/get-token"
},
{
"request":{
"url":"http://127.0.0.1:5000/api/users/1548560768589",
"method":"POST",
"headers":{
"User-Agent":"python-requests/2.18.4",
"device_sn":"$device_sn",
"token":"$token",
"Content-Type":"application/json"
},
"json":{
"name":"user1",
"password":"123456"
}
},
"validate":[
{
"eq":[
"status_code",
201
]
},
{
"eq":[
"headers.Content-Type",
"application/json"
]
},
{
"eq":[
"content.success",
true
]
},
{
"eq":[
"content.msg",
"user created successfully."
]
}
],
"verify":true,
"variables":{
"user_id":1548560768589,
"device_sn":"mmHBimjzK4Pk6mg"
},
"name":"/api/users/1548560768589"
}
],
"path":"/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner-docs-v2x/docs/data/demo-quickstart-6.json",
"type":"testcase"
}
]
}
+361
View File
@@ -0,0 +1,361 @@
{
"success":true,
"stat":{
"testcases":{
"total":1,
"success":1,
"fail":0
},
"teststeps":{
"total":2,
"failures":0,
"errors":0,
"skipped":0,
"expectedFailures":0,
"unexpectedSuccesses":0,
"successes":2
}
},
"time":{
"start_at":1548560768.590071,
"duration":0.036631107330322266
},
"platform":{
"httprunner_version":"2.0.2",
"python_version":"CPython 3.7.0",
"platform":"Darwin-18.2.0-x86_64-i386-64bit"
},
"details":[
{
"success":true,
"stat":{
"total":2,
"failures":0,
"errors":0,
"skipped":0,
"expectedFailures":0,
"unexpectedSuccesses":0,
"successes":2
},
"time":{
"start_at":1548560768.590071,
"duration":0.036631107330322266
},
"records":[
{
"name":"/api/get-token",
"status":"success",
"attachment":"",
"meta_datas":{
"name":"/api/get-token",
"data":[
{
"request":{
"url":"http://127.0.0.1:5000/api/get-token",
"method":"POST",
"headers":{
"User-Agent":"python-requests/2.18.4",
"Accept-Encoding":"gzip, deflate",
"Accept":"*/*",
"Connection":"keep-alive",
"device_sn":"mmHBimjzK4Pk6mg",
"os_platform":"ios",
"app_version":"2.8.6",
"Content-Type":"application/json",
"Content-Length":"52"
},
"body":"{&#34;sign&#34;: &#34;57885427ba4f3d55b6bce51827c5152a0f0f850f&#34;}"
},
"response":{
"ok":true,
"url":"http://127.0.0.1:5000/api/get-token",
"status_code":200,
"reason":"OK",
"cookies":{},
"encoding":"None",
"headers":{
"Content-Type":"application/json",
"Content-Length":"46",
"Server":"Werkzeug/0.14.1 Python/3.6.5+",
"Date":"Sun, 27 Jan 2019 03:46:08 GMT"
},
"content_type":"application/json",
"json":{
"success":true,
"token":"C3olNHYCMWfSQkCW"
}
}
}
],
"stat":{
"response_time_ms":11.42,
"elapsed_ms":3.71,
"content_size":46
},
"validators":[
{
"check":"status_code",
"expect":200,
"comparator":"eq",
"check_value":200,
"check_result":"pass"
},
{
"check":"headers.Content-Type",
"expect":"application/json",
"comparator":"eq",
"check_value":"application/json",
"check_result":"pass"
},
{
"check":"content.success",
"expect":true,
"comparator":"eq",
"check_value":true,
"check_result":"pass"
}
]
},
"meta_datas_expanded":[
{
"name":"/api/get-token",
"data":[
{
"request":{
"url":"http://127.0.0.1:5000/api/get-token",
"method":"POST",
"headers":{
"User-Agent":"python-requests/2.18.4",
"Accept-Encoding":"gzip, deflate",
"Accept":"*/*",
"Connection":"keep-alive",
"device_sn":"mmHBimjzK4Pk6mg",
"os_platform":"ios",
"app_version":"2.8.6",
"Content-Type":"application/json",
"Content-Length":"52"
},
"body":"{&#34;sign&#34;: &#34;57885427ba4f3d55b6bce51827c5152a0f0f850f&#34;}"
},
"response":{
"ok":true,
"url":"http://127.0.0.1:5000/api/get-token",
"status_code":200,
"reason":"OK",
"cookies":{},
"encoding":"None",
"headers":{
"Content-Type":"application/json",
"Content-Length":"46",
"Server":"Werkzeug/0.14.1 Python/3.6.5+",
"Date":"Sun, 27 Jan 2019 03:46:08 GMT"
},
"content_type":"application/json",
"json":{
"success":true,
"token":"C3olNHYCMWfSQkCW"
}
}
}
],
"stat":{
"response_time_ms":11.42,
"elapsed_ms":3.71,
"content_size":46
},
"validators":[
{
"check":"status_code",
"expect":200,
"comparator":"eq",
"check_value":200,
"check_result":"pass"
},
{
"check":"headers.Content-Type",
"expect":"application/json",
"comparator":"eq",
"check_value":"application/json",
"check_result":"pass"
},
{
"check":"content.success",
"expect":true,
"comparator":"eq",
"check_value":true,
"check_result":"pass"
}
]
}
],
"response_time":"11.42"
},
{
"name":"/api/users/1548560768589",
"status":"success",
"attachment":"",
"meta_datas":{
"name":"/api/users/1548560768589",
"data":[
{
"request":{
"url":"http://127.0.0.1:5000/api/users/1548560768589",
"method":"POST",
"headers":{
"User-Agent":"python-requests/2.18.4",
"Accept-Encoding":"gzip, deflate",
"Accept":"*/*",
"Connection":"keep-alive",
"device_sn":"mmHBimjzK4Pk6mg",
"token":"C3olNHYCMWfSQkCW",
"Content-Type":"application/json",
"Content-Length":"39"
},
"body":"{&#34;name&#34;: &#34;user1&#34;, &#34;password&#34;: &#34;123456&#34;}"
},
"response":{
"ok":true,
"url":"http://127.0.0.1:5000/api/users/1548560768589",
"status_code":201,
"reason":"CREATED",
"cookies":{},
"encoding":"None",
"headers":{
"Content-Type":"application/json",
"Content-Length":"54",
"Server":"Werkzeug/0.14.1 Python/3.6.5+",
"Date":"Sun, 27 Jan 2019 03:46:08 GMT"
},
"content_type":"application/json",
"json":{
"success":true,
"msg":"user created successfully."
}
}
}
],
"stat":{
"response_time_ms":2.8,
"elapsed_ms":1.748,
"content_size":54
},
"validators":[
{
"check":"status_code",
"expect":201,
"comparator":"eq",
"check_value":201,
"check_result":"pass"
},
{
"check":"headers.Content-Type",
"expect":"application/json",
"comparator":"eq",
"check_value":"application/json",
"check_result":"pass"
},
{
"check":"content.success",
"expect":true,
"comparator":"eq",
"check_value":true,
"check_result":"pass"
},
{
"check":"content.msg",
"expect":"user created successfully.",
"comparator":"eq",
"check_value":"user created successfully.",
"check_result":"pass"
}
]
},
"meta_datas_expanded":[
{
"name":"/api/users/1548560768589",
"data":[
{
"request":{
"url":"http://127.0.0.1:5000/api/users/1548560768589",
"method":"POST",
"headers":{
"User-Agent":"python-requests/2.18.4",
"Accept-Encoding":"gzip, deflate",
"Accept":"*/*",
"Connection":"keep-alive",
"device_sn":"mmHBimjzK4Pk6mg",
"token":"C3olNHYCMWfSQkCW",
"Content-Type":"application/json",
"Content-Length":"39"
},
"body":"{&#34;name&#34;: &#34;user1&#34;, &#34;password&#34;: &#34;123456&#34;}"
},
"response":{
"ok":true,
"url":"http://127.0.0.1:5000/api/users/1548560768589",
"status_code":201,
"reason":"CREATED",
"cookies":{},
"encoding":"None",
"headers":{
"Content-Type":"application/json",
"Content-Length":"54",
"Server":"Werkzeug/0.14.1 Python/3.6.5+",
"Date":"Sun, 27 Jan 2019 03:46:08 GMT"
},
"content_type":"application/json",
"json":{
"success":true,
"msg":"user created successfully."
}
}
}
],
"stat":{
"response_time_ms":2.8,
"elapsed_ms":1.748,
"content_size":54
},
"validators":[
{
"check":"status_code",
"expect":201,
"comparator":"eq",
"check_value":201,
"check_result":"pass"
},
{
"check":"headers.Content-Type",
"expect":"application/json",
"comparator":"eq",
"check_value":"application/json",
"check_result":"pass"
},
{
"check":"content.success",
"expect":true,
"comparator":"eq",
"check_value":true,
"check_result":"pass"
},
{
"check":"content.msg",
"expect":"user created successfully.",
"comparator":"eq",
"check_value":"user created successfully.",
"check_result":"pass"
}
]
}
],
"response_time":"2.80"
}
],
"name":"testcase description",
"in_out":{
"in":{},
"out":{}
}
}
]
}
+774
View File
@@ -0,0 +1,774 @@
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> - TestReport</title>
<style>
body {
background-color: #f2f2f2;
color: #333;
margin: 0 auto;
width: 960px;
}
#summary {
width: 960px;
margin-bottom: 20px;
}
#summary th {
background-color: skyblue;
padding: 5px 12px;
}
#summary td {
background-color: lightblue;
text-align: center;
padding: 4px 8px;
}
.details {
width: 960px;
margin-bottom: 20px;
}
.details th {
background-color: skyblue;
padding: 5px 12px;
}
.details tr .passed {
background-color: lightgreen;
}
.details tr .failed {
background-color: red;
}
.details tr .unchecked {
background-color: gray;
}
.details td {
background-color: lightblue;
padding: 5px 12px;
}
.details .detail {
background-color: lightgrey;
font-size: smaller;
padding: 5px 10px;
line-height: 20px;
text-align: left;
}
.details .success {
background-color: greenyellow;
}
.details .error {
background-color: red;
}
.details .failure {
background-color: salmon;
}
.details .skipped {
background-color: gray;
}
.button {
font-size: 1em;
padding: 6px;
width: 4em;
text-align: center;
background-color: #06d85f;
border-radius: 20px/50px;
cursor: pointer;
transition: all 0.3s ease-out;
}
a.button{
color: gray;
text-decoration: none;
display: inline-block;
}
.button:hover {
background: #2cffbd;
}
.overlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
line-height: 25px;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
margin: 70px auto;
padding: 20px;
background: #fff;
border-radius: 10px;
width: 50%;
position: relative;
transition: all 3s ease-in-out;
}
.popup h2 {
margin-top: 0;
color: #333;
font-family: Tahoma, Arial, sans-serif;
}
.popup .close {
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: #333;
}
.popup .close:hover {
color: #06d85f;
}
.popup .content {
max-height: 80%;
overflow: auto;
text-align: left;
}
.popup .separator {
color:royalblue
}
@media screen and (max-width: 700px) {
.box {
width: 70%;
}
.popup {
width: 70%;
}
}
</style>
</head>
<body>
<h1>Test Report: </h1>
<h2>Summary</h2>
<table id="summary">
<tr>
<th>START AT</th>
<td colspan="4">2019-01-27 11:52:50</td>
</tr>
<tr>
<th>DURATION</th>
<td colspan="4">0.039 seconds</td>
</tr>
<tr>
<th>PLATFORM</th>
<td>HttpRunner 2.0.2 </td>
<td>CPython 3.7.0 </td>
<td colspan="2">Darwin-18.2.0-x86_64-i386-64bit</td>
</tr>
<tr>
<th>STAT</th>
<th colspan="2">TESTCASES (success/fail)</th>
<th colspan="2">TESTSTEPS (success/fail/error/skip)</th>
</tr>
<tr>
<td>total (details) =></td>
<td colspan="2">1 (1/0)</td>
<td colspan="2">2 (2/0/0/0)</td>
</tr>
</table>
<h2>Details</h2>
<h3>testcase description</h3>
<table id="suite_1" class="details">
<tr>
<td>TOTAL: 2</td>
<td>SUCCESS: 2</td>
<td>FAILED: 0</td>
<td>ERROR: 0</td>
<td>SKIPPED: 0</td>
</tr>
<tr>
<th>Status</th>
<th colspan="2">Name</th>
<th>Response Time</th>
<th>Detail</th>
</tr>
<tr id="record_1_1">
<th class="success" style="width:5em;">success</th>
<td colspan="2">/api/get-token</td>
<td style="text-align:center;width:6em;">10.05 ms</td>
<td class="detail">
<a class="button" href="#popup_log_1_1_1">log-1</a>
<div id="popup_log_1_1_1" class="overlay">
<div class="popup">
<h2>Request and Response data</h2>
<a class="close" href="#record_1_1_1">&times;</a>
<div class="content">
<h3>Name: /api/get-token</h3>
<h3>Request:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>url</th>
<td>
http://127.0.0.1:5000/api/get-token
</td>
</tr>
<tr>
<th>method</th>
<td>
POST
</td>
</tr>
<tr>
<th>headers</th>
<td>
<div>
<strong>User-Agent</strong>: python-requests/2.18.4
</div>
<div>
<strong>Accept-Encoding</strong>: gzip, deflate
</div>
<div>
<strong>Accept</strong>: */*
</div>
<div>
<strong>Connection</strong>: keep-alive
</div>
<div>
<strong>Content-Type</strong>: application/json
</div>
<div>
<strong>app_version</strong>: 2.8.6
</div>
<div>
<strong>device_sn</strong>: rmZg1EL9KrDTxKB
</div>
<div>
<strong>os_platform</strong>: ios
</div>
<div>
<strong>Content-Length</strong>: 52
</div>
</td>
</tr>
<tr>
<th>body</th>
<td>
{&#34;sign&#34;: &#34;bd37c4f16cacb2bede7d9c853cc86b1fe36bfce6&#34;}
</td>
</tr>
</table>
</div>
<h3>Response:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>ok</th>
<td>
True
</td>
</tr>
<tr>
<th>url</th>
<td>
http://127.0.0.1:5000/api/get-token
</td>
</tr>
<tr>
<th>status_code</th>
<td>
200
</td>
</tr>
<tr>
<th>reason</th>
<td>
OK
</td>
</tr>
<tr>
<th>cookies</th>
<td>
{}
</td>
</tr>
<tr>
<th>encoding</th>
<td>
None
</td>
</tr>
<tr>
<th>headers</th>
<td>
<div>
<strong>Content-Type</strong>: application/json
</div>
<div>
<strong>Content-Length</strong>: 46
</div>
<div>
<strong>Server</strong>: Werkzeug/0.14.1 Python/3.6.5+
</div>
<div>
<strong>Date</strong>: Sun, 27 Jan 2019 03:52:50 GMT
</div>
</td>
</tr>
<tr>
<th>content_type</th>
<td>
application/json
</td>
</tr>
<tr>
<th>json</th>
<td>
{'success': True, 'token': 'PQTsjHOpmXulNB3l'}
</td>
</tr>
</table>
</div>
<h3>Validators:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>check</th>
<th>comparator</th>
<th>expect value</th>
<th>actual value</th>
</tr>
<tr>
<td class="passed">
status_code
</td>
<td>eq</td>
<td>200</td>
<td>200</td>
</tr>
<tr>
<td class="passed">
headers.Content-Type
</td>
<td>eq</td>
<td>application/json</td>
<td>application/json</td>
</tr>
<tr>
<td class="passed">
content.success
</td>
<td>eq</td>
<td>True</td>
<td>True</td>
</tr>
</table>
</div>
<h3>Statistics:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>content_size(bytes)</th>
<td>46</td>
</tr>
<tr>
<th>response_time(ms)</th>
<td>10.05</td>
</tr>
<tr>
<th>elapsed(ms)</th>
<td>3.483</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</td>
</tr>
<tr id="record_1_2">
<th class="success" style="width:5em;">success</th>
<td colspan="2">/api/users/1548561170497</td>
<td style="text-align:center;width:6em;">2.88 ms</td>
<td class="detail">
<a class="button" href="#popup_log_1_2_1">log-1</a>
<div id="popup_log_1_2_1" class="overlay">
<div class="popup">
<h2>Request and Response data</h2>
<a class="close" href="#record_1_2_1">&times;</a>
<div class="content">
<h3>Name: /api/users/1548561170497</h3>
<h3>Request:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>url</th>
<td>
http://127.0.0.1:5000/api/users/1548561170497
</td>
</tr>
<tr>
<th>method</th>
<td>
POST
</td>
</tr>
<tr>
<th>headers</th>
<td>
<div>
<strong>User-Agent</strong>: python-requests/2.18.4
</div>
<div>
<strong>Accept-Encoding</strong>: gzip, deflate
</div>
<div>
<strong>Accept</strong>: */*
</div>
<div>
<strong>Connection</strong>: keep-alive
</div>
<div>
<strong>Content-Type</strong>: application/json
</div>
<div>
<strong>device_sn</strong>: rmZg1EL9KrDTxKB
</div>
<div>
<strong>token</strong>: PQTsjHOpmXulNB3l
</div>
<div>
<strong>Content-Length</strong>: 39
</div>
</td>
</tr>
<tr>
<th>body</th>
<td>
{&#34;name&#34;: &#34;user1&#34;, &#34;password&#34;: &#34;123456&#34;}
</td>
</tr>
</table>
</div>
<h3>Response:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>ok</th>
<td>
True
</td>
</tr>
<tr>
<th>url</th>
<td>
http://127.0.0.1:5000/api/users/1548561170497
</td>
</tr>
<tr>
<th>status_code</th>
<td>
201
</td>
</tr>
<tr>
<th>reason</th>
<td>
CREATED
</td>
</tr>
<tr>
<th>cookies</th>
<td>
{}
</td>
</tr>
<tr>
<th>encoding</th>
<td>
None
</td>
</tr>
<tr>
<th>headers</th>
<td>
<div>
<strong>Content-Type</strong>: application/json
</div>
<div>
<strong>Content-Length</strong>: 54
</div>
<div>
<strong>Server</strong>: Werkzeug/0.14.1 Python/3.6.5+
</div>
<div>
<strong>Date</strong>: Sun, 27 Jan 2019 03:52:50 GMT
</div>
</td>
</tr>
<tr>
<th>content_type</th>
<td>
application/json
</td>
</tr>
<tr>
<th>json</th>
<td>
{'success': True, 'msg': 'user created successfully.'}
</td>
</tr>
</table>
</div>
<h3>Validators:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>check</th>
<th>comparator</th>
<th>expect value</th>
<th>actual value</th>
</tr>
<tr>
<td class="passed">
status_code
</td>
<td>eq</td>
<td>201</td>
<td>201</td>
</tr>
<tr>
<td class="passed">
headers.Content-Type
</td>
<td>eq</td>
<td>application/json</td>
<td>application/json</td>
</tr>
<tr>
<td class="passed">
content.success
</td>
<td>eq</td>
<td>True</td>
<td>True</td>
</tr>
<tr>
<td class="passed">
content.msg
</td>
<td>eq</td>
<td>user created successfully.</td>
<td>user created successfully.</td>
</tr>
</table>
</div>
<h3>Statistics:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>content_size(bytes)</th>
<td>54</td>
</tr>
<tr>
<th>response_time(ms)</th>
<td>2.88</td>
</tr>
<tr>
<th>elapsed(ms)</th>
<td>1.869</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</td>
</tr>
</table>
</body>
+804
View File
@@ -0,0 +1,804 @@
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> - TestReport</title>
<style>
body {
background-color: #f2f2f2;
color: #333;
margin: 0 auto;
width: 960px;
}
#summary {
width: 960px;
margin-bottom: 20px;
}
#summary th {
background-color: skyblue;
padding: 5px 12px;
}
#summary td {
background-color: lightblue;
text-align: center;
padding: 4px 8px;
}
.details {
width: 960px;
margin-bottom: 20px;
}
.details th {
background-color: skyblue;
padding: 5px 12px;
}
.details tr .passed {
background-color: lightgreen;
}
.details tr .failed {
background-color: red;
}
.details tr .unchecked {
background-color: gray;
}
.details td {
background-color: lightblue;
padding: 5px 12px;
}
.details .detail {
background-color: lightgrey;
font-size: smaller;
padding: 5px 10px;
line-height: 20px;
text-align: left;
}
.details .success {
background-color: greenyellow;
}
.details .error {
background-color: red;
}
.details .failure {
background-color: salmon;
}
.details .skipped {
background-color: gray;
}
.button {
font-size: 1em;
padding: 6px;
width: 4em;
text-align: center;
background-color: #06d85f;
border-radius: 20px/50px;
cursor: pointer;
transition: all 0.3s ease-out;
}
a.button{
color: gray;
text-decoration: none;
display: inline-block;
}
.button:hover {
background: #2cffbd;
}
.overlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
line-height: 25px;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
margin: 70px auto;
padding: 20px;
background: #fff;
border-radius: 10px;
width: 50%;
position: relative;
transition: all 3s ease-in-out;
}
.popup h2 {
margin-top: 0;
color: #333;
font-family: Tahoma, Arial, sans-serif;
}
.popup .close {
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: #333;
}
.popup .close:hover {
color: #06d85f;
}
.popup .content {
max-height: 80%;
overflow: auto;
text-align: left;
}
.popup .separator {
color:royalblue
}
@media screen and (max-width: 700px) {
.box {
width: 70%;
}
.popup {
width: 70%;
}
}
</style>
</head>
<body>
<h1>Test Report: </h1>
<h2>Summary</h2>
<table id="summary">
<tr>
<th>START AT</th>
<td colspan="4">2019-01-27 11:57:44</td>
</tr>
<tr>
<th>DURATION</th>
<td colspan="4">0.035 seconds</td>
</tr>
<tr>
<th>PLATFORM</th>
<td>HttpRunner 2.0.2 </td>
<td>CPython 3.7.0 </td>
<td colspan="2">Darwin-18.2.0-x86_64-i386-64bit</td>
</tr>
<tr>
<th>STAT</th>
<th colspan="2">TESTCASES (success/fail)</th>
<th colspan="2">TESTSTEPS (success/fail/error/skip)</th>
</tr>
<tr>
<td>total (details) =></td>
<td colspan="2">1 (0/1)</td>
<td colspan="2">2 (1/1/0/0)</td>
</tr>
</table>
<h2>Details</h2>
<h3>testcase description</h3>
<table id="suite_1" class="details">
<tr>
<td>TOTAL: 2</td>
<td>SUCCESS: 1</td>
<td>FAILED: 1</td>
<td>ERROR: 0</td>
<td>SKIPPED: 0</td>
</tr>
<tr>
<th>Status</th>
<th colspan="2">Name</th>
<th>Response Time</th>
<th>Detail</th>
</tr>
<tr id="record_1_1">
<th class="success" style="width:5em;">success</th>
<td colspan="2">/api/get-token</td>
<td style="text-align:center;width:6em;">9.01 ms</td>
<td class="detail">
<a class="button" href="#popup_log_1_1_1">log-1</a>
<div id="popup_log_1_1_1" class="overlay">
<div class="popup">
<h2>Request and Response data</h2>
<a class="close" href="#record_1_1_1">&times;</a>
<div class="content">
<h3>Name: /api/get-token</h3>
<h3>Request:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>url</th>
<td>
http://127.0.0.1:5000/api/get-token
</td>
</tr>
<tr>
<th>method</th>
<td>
POST
</td>
</tr>
<tr>
<th>headers</th>
<td>
<div>
<strong>User-Agent</strong>: python-requests/2.18.4
</div>
<div>
<strong>Accept-Encoding</strong>: gzip, deflate
</div>
<div>
<strong>Accept</strong>: */*
</div>
<div>
<strong>Connection</strong>: keep-alive
</div>
<div>
<strong>Content-Type</strong>: application/json
</div>
<div>
<strong>app_version</strong>: 2.8.6
</div>
<div>
<strong>device_sn</strong>: FwgRiO7CNA50DSU
</div>
<div>
<strong>os_platform</strong>: ios
</div>
<div>
<strong>Content-Length</strong>: 52
</div>
</td>
</tr>
<tr>
<th>body</th>
<td>
{&#34;sign&#34;: &#34;9c0c7e51c91ae963c833a4ccbab8d683c4a90c98&#34;}
</td>
</tr>
</table>
</div>
<h3>Response:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>ok</th>
<td>
True
</td>
</tr>
<tr>
<th>url</th>
<td>
http://127.0.0.1:5000/api/get-token
</td>
</tr>
<tr>
<th>status_code</th>
<td>
200
</td>
</tr>
<tr>
<th>reason</th>
<td>
OK
</td>
</tr>
<tr>
<th>cookies</th>
<td>
{}
</td>
</tr>
<tr>
<th>encoding</th>
<td>
None
</td>
</tr>
<tr>
<th>headers</th>
<td>
<div>
<strong>Content-Type</strong>: application/json
</div>
<div>
<strong>Content-Length</strong>: 46
</div>
<div>
<strong>Server</strong>: Werkzeug/0.14.1 Python/3.6.5+
</div>
<div>
<strong>Date</strong>: Sun, 27 Jan 2019 03:57:44 GMT
</div>
</td>
</tr>
<tr>
<th>content_type</th>
<td>
application/json
</td>
</tr>
<tr>
<th>json</th>
<td>
{'success': True, 'token': 'm7Lq6XCTELA14GB0'}
</td>
</tr>
</table>
</div>
<h3>Validators:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>check</th>
<th>comparator</th>
<th>expect value</th>
<th>actual value</th>
</tr>
<tr>
<td class="passed">
status_code
</td>
<td>eq</td>
<td>200</td>
<td>200</td>
</tr>
<tr>
<td class="passed">
headers.Content-Type
</td>
<td>eq</td>
<td>application/json</td>
<td>application/json</td>
</tr>
<tr>
<td class="passed">
content.success
</td>
<td>eq</td>
<td>True</td>
<td>True</td>
</tr>
</table>
</div>
<h3>Statistics:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>content_size(bytes)</th>
<td>46</td>
</tr>
<tr>
<th>response_time(ms)</th>
<td>9.01</td>
</tr>
<tr>
<th>elapsed(ms)</th>
<td>2.396</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</td>
</tr>
<tr id="record_1_2">
<th class="failure" style="width:5em;">failure</th>
<td colspan="2">/api/users/1000</td>
<td style="text-align:center;width:6em;">2.62 ms</td>
<td class="detail">
<a class="button" href="#popup_log_1_2_1">log-1</a>
<div id="popup_log_1_2_1" class="overlay">
<div class="popup">
<h2>Request and Response data</h2>
<a class="close" href="#record_1_2_1">&times;</a>
<div class="content">
<h3>Name: /api/users/1000</h3>
<h3>Request:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>url</th>
<td>
http://127.0.0.1:5000/api/users/1000
</td>
</tr>
<tr>
<th>method</th>
<td>
POST
</td>
</tr>
<tr>
<th>headers</th>
<td>
<div>
<strong>User-Agent</strong>: python-requests/2.18.4
</div>
<div>
<strong>Accept-Encoding</strong>: gzip, deflate
</div>
<div>
<strong>Accept</strong>: */*
</div>
<div>
<strong>Connection</strong>: keep-alive
</div>
<div>
<strong>Content-Type</strong>: application/json
</div>
<div>
<strong>device_sn</strong>: FwgRiO7CNA50DSU
</div>
<div>
<strong>token</strong>: baNLX1zhFYP11Seb
</div>
<div>
<strong>Content-Length</strong>: 39
</div>
</td>
</tr>
<tr>
<th>body</th>
<td>
{&#34;name&#34;: &#34;user1&#34;, &#34;password&#34;: &#34;123456&#34;}
</td>
</tr>
</table>
</div>
<h3>Response:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>ok</th>
<td>
False
</td>
</tr>
<tr>
<th>url</th>
<td>
http://127.0.0.1:5000/api/users/1000
</td>
</tr>
<tr>
<th>status_code</th>
<td>
403
</td>
</tr>
<tr>
<th>reason</th>
<td>
FORBIDDEN
</td>
</tr>
<tr>
<th>cookies</th>
<td>
{}
</td>
</tr>
<tr>
<th>encoding</th>
<td>
None
</td>
</tr>
<tr>
<th>headers</th>
<td>
<div>
<strong>Content-Type</strong>: application/json
</div>
<div>
<strong>Content-Length</strong>: 50
</div>
<div>
<strong>Server</strong>: Werkzeug/0.14.1 Python/3.6.5+
</div>
<div>
<strong>Date</strong>: Sun, 27 Jan 2019 03:57:44 GMT
</div>
</td>
</tr>
<tr>
<th>content_type</th>
<td>
application/json
</td>
</tr>
<tr>
<th>json</th>
<td>
{'success': False, 'msg': 'Authorization failed!'}
</td>
</tr>
</table>
</div>
<h3>Validators:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>check</th>
<th>comparator</th>
<th>expect value</th>
<th>actual value</th>
</tr>
<tr>
<td class="failed">
status_code
</td>
<td>eq</td>
<td>201</td>
<td>403</td>
</tr>
<tr>
<td class="passed">
headers.Content-Type
</td>
<td>eq</td>
<td>application/json</td>
<td>application/json</td>
</tr>
<tr>
<td class="failed">
content.success
</td>
<td>eq</td>
<td>True</td>
<td>False</td>
</tr>
<tr>
<td class="failed">
content.msg
</td>
<td>eq</td>
<td>user created successfully.</td>
<td>Authorization failed!</td>
</tr>
</table>
</div>
<h3>Statistics:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>content_size(bytes)</th>
<td>50</td>
</tr>
<tr>
<th>response_time(ms)</th>
<td>2.62</td>
</tr>
<tr>
<th>elapsed(ms)</th>
<td>1.648</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<a class="button" href="#popup_attachment_1_2">traceback</a>
<div id="popup_attachment_1_2" class="overlay">
<div class="popup">
<h2>Traceback Message</h2>
<a class="close" href="#record_1_2">&times;</a>
<div class="content"><pre>Traceback (most recent call last):
File &#34;/Users/debugtalk/.venv/httprunner/lib/python3.7/site-packages/HttpRunner-2.0.2-py3.7.egg/httprunner/api.py&#34;, line 54, in test
test_runner.run_test(test_dict)
httprunner.exceptions.ValidationFailure: validate: status_code equals 201(int) ==&gt; fail
403(int) equals 201(int)
validate: content.success equals True(bool) ==&gt; fail
False(bool) equals True(bool)
validate: content.msg equals user created successfully.(str) ==&gt; fail
Authorization failed!(str) equals user created successfully.(str)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File &#34;/Users/debugtalk/.venv/httprunner/lib/python3.7/site-packages/HttpRunner-2.0.2-py3.7.egg/httprunner/api.py&#34;, line 56, in test
self.fail(str(ex))
AssertionError: validate: status_code equals 201(int) ==&gt; fail
403(int) equals 201(int)
validate: content.success equals True(bool) ==&gt; fail
False(bool) equals True(bool)
validate: content.msg equals user created successfully.(str) ==&gt; fail
Authorization failed!(str) equals user created successfully.(str)
</pre></div>
</div>
</div>
</td>
</tr>
</table>
</body>
File diff suppressed because one or more lines are too long
+66
View File
@@ -0,0 +1,66 @@
- config:
name: testcase description
variables: {}
verify: False
- test:
name: /account/sign_in
request:
headers:
If-None-Match: W/"bc9ae267fdcbd89bf1dfaea10dea2b0e"
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
method: GET
url: https://testerhome.com/account/sign_in
extract:
X_CSRF_Token: <meta name="csrf-token" content="(.*)" />
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, text/html; charset=utf-8]
- test:
name: /assets/big_logo-cd32144f74c18746f3dce33e1040e7dfe4c07c8e611e37f3868b1c16b5095da3.png
request:
headers:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
method: GET
url: https://testerhome.com/assets/big_logo-cd32144f74c18746f3dce33e1040e7dfe4c07c8e611e37f3868b1c16b5095da3.png
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, image/png]
- test:
name: /account/sign_in
request:
data:
commit: Sign In
user[login]: debugtalk
user[password]: XXXXXXXX
user[remember_me]: '1'
utf8:
headers:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
X-CSRF-Token: $X_CSRF_Token
X-Requested-With: XMLHttpRequest
method: POST
url: https://testerhome.com/account/sign_in
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, text/javascript; charset=utf-8]
- test:
name: /
request:
headers:
If-None-Match: W/"bad62c68dac27b01151516aad5c7f0be"
Turbolinks-Referrer: https://testerhome.com/account/sign_in
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
method: GET
url: https://testerhome.com/
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, text/html; charset=utf-8]
+5
View File
@@ -0,0 +1,5 @@
user_id
1001
1002
1003
1004
1 user_id
2 1001
3 1002
4 1003
5 1004