mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 15:37:35 +08:00
@@ -1,7 +1,7 @@
|
|||||||
__title__ = 'HttpRunner'
|
__title__ = 'HttpRunner'
|
||||||
__description__ = 'One-stop solution for HTTP(S) testing.'
|
__description__ = 'One-stop solution for HTTP(S) testing.'
|
||||||
__url__ = 'https://github.com/HttpRunner/HttpRunner'
|
__url__ = 'https://github.com/HttpRunner/HttpRunner'
|
||||||
__version__ = '1.5.14'
|
__version__ = '1.5.15'
|
||||||
__author__ = 'debugtalk'
|
__author__ = 'debugtalk'
|
||||||
__author_email__ = 'mail@debugtalk.com'
|
__author_email__ = 'mail@debugtalk.com'
|
||||||
__license__ = 'MIT'
|
__license__ = 'MIT'
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from httprunner.api import HttpRunner, LocustRunner
|
from httprunner.api import HttpRunner
|
||||||
|
|||||||
@@ -255,22 +255,3 @@ class HttpRunner(object):
|
|||||||
html_report_name,
|
html_report_name,
|
||||||
html_report_template
|
html_report_template
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class LocustRunner(object):
|
|
||||||
|
|
||||||
def __init__(self, locust_client):
|
|
||||||
self.runner = HttpRunner(http_client_session=locust_client)
|
|
||||||
|
|
||||||
def run(self, path):
|
|
||||||
try:
|
|
||||||
self.runner.run(path)
|
|
||||||
except exceptions.MyBaseError as ex:
|
|
||||||
# TODO: refactor
|
|
||||||
from locust.events import request_failure
|
|
||||||
request_failure.fire(
|
|
||||||
request_type=test.testcase_dict.get("request", {}).get("method"),
|
|
||||||
name=test.testcase_dict.get("request", {}).get("url"),
|
|
||||||
response_time=0,
|
|
||||||
exception=ex
|
|
||||||
)
|
|
||||||
|
|||||||
+28
-7
@@ -101,14 +101,12 @@ def main_hrun():
|
|||||||
def main_locust():
|
def main_locust():
|
||||||
""" Performance test with locust: parse command line options and run commands.
|
""" Performance test with locust: parse command line options and run commands.
|
||||||
"""
|
"""
|
||||||
logger.setup_logger("INFO")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from httprunner import locusts
|
from httprunner import locusts
|
||||||
except ImportError:
|
except ImportError:
|
||||||
msg = "Locust is not installed, install first and try again.\n"
|
msg = "Locust is not installed, install first and try again.\n"
|
||||||
msg += "install command: pip install locustio"
|
msg += "install command: pip install locustio"
|
||||||
logger.log_warning(msg)
|
print(msg)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
sys.argv[0] = 'locust'
|
sys.argv[0] = 'locust'
|
||||||
@@ -119,11 +117,34 @@ def main_locust():
|
|||||||
locusts.main()
|
locusts.main()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
# set logging level
|
||||||
|
if "-L" in sys.argv:
|
||||||
|
loglevel_index = sys.argv.index('-L') + 1
|
||||||
|
elif "--loglevel" in sys.argv:
|
||||||
|
loglevel_index = sys.argv.index('--loglevel') + 1
|
||||||
|
else:
|
||||||
|
loglevel_index = None
|
||||||
|
|
||||||
|
if loglevel_index and loglevel_index < len(sys.argv):
|
||||||
|
loglevel = sys.argv[loglevel_index]
|
||||||
|
else:
|
||||||
|
# default
|
||||||
|
loglevel = "INFO"
|
||||||
|
|
||||||
|
logger.setup_logger(loglevel)
|
||||||
|
|
||||||
|
# get testcase file path
|
||||||
try:
|
try:
|
||||||
testcase_index = sys.argv.index('-f') + 1
|
if "-f" in sys.argv:
|
||||||
assert testcase_index < len(sys.argv)
|
testcase_index = sys.argv.index('-f') + 1
|
||||||
except (ValueError, AssertionError):
|
elif "--locustfile" in sys.argv:
|
||||||
logger.log_error("Testcase file is not specified, exit.")
|
testcase_index = sys.argv.index('--locustfile') + 1
|
||||||
|
else:
|
||||||
|
testcase_index = None
|
||||||
|
|
||||||
|
assert testcase_index and testcase_index < len(sys.argv)
|
||||||
|
except AssertionError:
|
||||||
|
print("Testcase file is not specified, exit.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
testcase_file_path = sys.argv[testcase_index]
|
testcase_file_path = sys.argv[testcase_index]
|
||||||
|
|||||||
@@ -14,8 +14,13 @@ class Context(object):
|
|||||||
""" init Context with testcase variables and functions.
|
""" init Context with testcase variables and functions.
|
||||||
"""
|
"""
|
||||||
# testcase level context
|
# testcase level context
|
||||||
## TESTCASE_SHARED_VARIABLES_MAPPING and TESTCASE_SHARED_FUNCTIONS_MAPPING will not change.
|
## TESTCASE_SHARED_VARIABLES_MAPPING and TESTCASE_SHARED_FUNCTIONS_MAPPING are unchangeable.
|
||||||
self.TESTCASE_SHARED_VARIABLES_MAPPING = variables or OrderedDict()
|
if isinstance(variables, list):
|
||||||
|
self.TESTCASE_SHARED_VARIABLES_MAPPING = utils.convert_mappinglist_to_orderdict(variables)
|
||||||
|
else:
|
||||||
|
# dict
|
||||||
|
self.TESTCASE_SHARED_VARIABLES_MAPPING = variables or OrderedDict()
|
||||||
|
|
||||||
self.TESTCASE_SHARED_FUNCTIONS_MAPPING = functions or OrderedDict()
|
self.TESTCASE_SHARED_FUNCTIONS_MAPPING = functions or OrderedDict()
|
||||||
|
|
||||||
# testcase level request, will not change
|
# testcase level request, will not change
|
||||||
|
|||||||
+122
-53
@@ -315,12 +315,70 @@ def get_module_item(module_mapping, item_type, item_name):
|
|||||||
## testcase loader
|
## testcase loader
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
def _load_test_file(file_path, project_mapping):
|
def _load_teststeps(test_block, project_mapping):
|
||||||
""" load testcase file or testsuite file
|
""" load teststeps with api/testcase references
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file_path (str): absolute valid file path. file_path should be in the following format:
|
test_block (dict): test block content, maybe in 3 formats.
|
||||||
|
# api reference
|
||||||
|
{
|
||||||
|
"name": "add product to cart",
|
||||||
|
"api": "api_add_cart()",
|
||||||
|
"validate": []
|
||||||
|
}
|
||||||
|
# testcase reference
|
||||||
|
{
|
||||||
|
"name": "add product to cart",
|
||||||
|
"suite": "create_and_check()",
|
||||||
|
"validate": []
|
||||||
|
}
|
||||||
|
# define directly
|
||||||
|
{
|
||||||
|
"name": "checkout cart",
|
||||||
|
"request": {},
|
||||||
|
"validate": []
|
||||||
|
}
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: loaded teststeps list
|
||||||
|
|
||||||
|
"""
|
||||||
|
def extend_api_definition(block):
|
||||||
|
ref_call = block["api"]
|
||||||
|
def_block = _get_block_by_name(ref_call, "def-api", project_mapping)
|
||||||
|
_extend_block(block, def_block)
|
||||||
|
|
||||||
|
teststeps = []
|
||||||
|
|
||||||
|
# reference api
|
||||||
|
if "api" in test_block:
|
||||||
|
extend_api_definition(test_block)
|
||||||
|
teststeps.append(test_block)
|
||||||
|
|
||||||
|
# reference testcase
|
||||||
|
elif "suite" in test_block: # TODO: replace suite with testcase
|
||||||
|
ref_call = test_block["suite"]
|
||||||
|
block = _get_block_by_name(ref_call, "def-testcase", project_mapping)
|
||||||
|
# TODO: bugfix lost block config variables
|
||||||
|
for teststep in block["teststeps"]:
|
||||||
|
if "api" in teststep:
|
||||||
|
extend_api_definition(teststep)
|
||||||
|
teststeps.append(teststep)
|
||||||
|
|
||||||
|
# define directly
|
||||||
|
else:
|
||||||
|
teststeps.append(test_block)
|
||||||
|
|
||||||
|
return teststeps
|
||||||
|
|
||||||
|
|
||||||
|
def _load_testcase(raw_testcase, project_mapping):
|
||||||
|
""" load testcase/testsuite with api/testcase references
|
||||||
|
|
||||||
|
Args:
|
||||||
|
raw_testcase (list): raw testcase content loaded from JSON/YAML file:
|
||||||
[
|
[
|
||||||
|
# config part
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"name": "",
|
"name": "",
|
||||||
@@ -328,87 +386,50 @@ def _load_test_file(file_path, project_mapping):
|
|||||||
"request": {}
|
"request": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
# teststeps part
|
||||||
{
|
{
|
||||||
"test": {
|
"test": {...}
|
||||||
"name": "add product to cart",
|
|
||||||
"api": "api_add_cart()",
|
|
||||||
"validate": []
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"test": {
|
"test": {...}
|
||||||
"name": "add product to cart",
|
|
||||||
"suite": "create_and_check()",
|
|
||||||
"validate": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"test": {
|
|
||||||
"name": "checkout cart",
|
|
||||||
"request": {},
|
|
||||||
"validate": []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
project_mapping (dict): project_mapping
|
project_mapping (dict): project_mapping
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: testcase dict
|
dict: loaded testcase content
|
||||||
{
|
{
|
||||||
"config": {},
|
"config": {},
|
||||||
"teststeps": [teststep11, teststep12]
|
"teststeps": [teststep11, teststep12]
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
testcase = {
|
loaded_testcase = {
|
||||||
"config": {},
|
"config": {},
|
||||||
"teststeps": []
|
"teststeps": []
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in load_file(file_path):
|
for item in raw_testcase:
|
||||||
# TODO: add json schema validation
|
# TODO: add json schema validation
|
||||||
if not isinstance(item, dict) or len(item) != 1:
|
if not isinstance(item, dict) or len(item) != 1:
|
||||||
raise exceptions.FileFormatError("Testcase format error: {}".format(file_path))
|
raise exceptions.FileFormatError("Testcase format error: {}".format(item))
|
||||||
|
|
||||||
key, test_block = item.popitem()
|
key, test_block = item.popitem()
|
||||||
if not isinstance(test_block, dict):
|
if not isinstance(test_block, dict):
|
||||||
raise exceptions.FileFormatError("Testcase format error: {}".format(file_path))
|
raise exceptions.FileFormatError("Testcase format error: {}".format(item))
|
||||||
|
|
||||||
if key == "config":
|
if key == "config":
|
||||||
testcase["config"].update(test_block)
|
loaded_testcase["config"].update(test_block)
|
||||||
|
|
||||||
elif key == "test":
|
elif key == "test":
|
||||||
|
loaded_testcase["teststeps"].extend(_load_teststeps(test_block, project_mapping))
|
||||||
def extend_api_definition(block):
|
|
||||||
ref_call = block["api"]
|
|
||||||
def_block = _get_block_by_name(ref_call, "def-api", project_mapping)
|
|
||||||
_extend_block(block, def_block)
|
|
||||||
|
|
||||||
# reference api
|
|
||||||
if "api" in test_block:
|
|
||||||
extend_api_definition(test_block)
|
|
||||||
testcase["teststeps"].append(test_block)
|
|
||||||
|
|
||||||
# reference testcase
|
|
||||||
elif "suite" in test_block: # TODO: replace suite with testcase
|
|
||||||
ref_call = test_block["suite"]
|
|
||||||
block = _get_block_by_name(ref_call, "def-testcase", project_mapping)
|
|
||||||
# TODO: bugfix lost block config variables
|
|
||||||
for teststep in block["teststeps"]:
|
|
||||||
if "api" in teststep:
|
|
||||||
extend_api_definition(teststep)
|
|
||||||
testcase["teststeps"].append(teststep)
|
|
||||||
|
|
||||||
# define directly
|
|
||||||
else:
|
|
||||||
testcase["teststeps"].append(test_block)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.log_warning(
|
logger.log_warning(
|
||||||
"unexpected block key: {}. block key should only be 'config' or 'test'.".format(key)
|
"unexpected block key: {}. block key should only be 'config' or 'test'.".format(key)
|
||||||
)
|
)
|
||||||
|
|
||||||
return testcase
|
return loaded_testcase
|
||||||
|
|
||||||
|
|
||||||
def _get_block_by_name(ref_call, ref_type, project_mapping):
|
def _get_block_by_name(ref_call, ref_type, project_mapping):
|
||||||
@@ -917,7 +938,7 @@ def load_tests(path, dot_env_path=None):
|
|||||||
"teststeps": [
|
"teststeps": [
|
||||||
# teststep data structure
|
# teststep data structure
|
||||||
{
|
{
|
||||||
'name': 'test step desc2',
|
'name': 'test step desc1',
|
||||||
'variables': [], # optional
|
'variables': [], # optional
|
||||||
'extract': [], # optional
|
'extract': [], # optional
|
||||||
'validate': [],
|
'validate': [],
|
||||||
@@ -956,8 +977,9 @@ def load_tests(path, dot_env_path=None):
|
|||||||
|
|
||||||
elif os.path.isfile(path):
|
elif os.path.isfile(path):
|
||||||
try:
|
try:
|
||||||
|
raw_testcase = load_file(path)
|
||||||
project_mapping = load_project_tests(path, dot_env_path)
|
project_mapping = load_project_tests(path, dot_env_path)
|
||||||
testcase = _load_test_file(path, project_mapping)
|
testcase = _load_testcase(raw_testcase, project_mapping)
|
||||||
testcase["config"]["path"] = path
|
testcase["config"]["path"] = path
|
||||||
testcase["config"]["refs"] = project_mapping
|
testcase["config"]["refs"] = project_mapping
|
||||||
testcases_list = [testcase]
|
testcases_list = [testcase]
|
||||||
@@ -965,3 +987,50 @@ def load_tests(path, dot_env_path=None):
|
|||||||
testcases_list = []
|
testcases_list = []
|
||||||
|
|
||||||
return testcases_list
|
return testcases_list
|
||||||
|
|
||||||
|
|
||||||
|
def load_locust_tests(path, dot_env_path=None):
|
||||||
|
""" load locust testcases
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (str): testcase/testsuite file path.
|
||||||
|
dot_env_path (str): specified .env file path
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: locust testcases with weight
|
||||||
|
{
|
||||||
|
"config": {...},
|
||||||
|
"tests": [
|
||||||
|
# weight 3
|
||||||
|
[teststep11],
|
||||||
|
[teststep11],
|
||||||
|
[teststep11],
|
||||||
|
# weight 2
|
||||||
|
[teststep21, teststep22],
|
||||||
|
[teststep21, teststep22]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
raw_testcase = load_file(path)
|
||||||
|
project_mapping = load_project_tests(path, dot_env_path)
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"refs": project_mapping
|
||||||
|
}
|
||||||
|
tests = []
|
||||||
|
for item in raw_testcase:
|
||||||
|
key, test_block = item.popitem()
|
||||||
|
|
||||||
|
if key == "config":
|
||||||
|
config.update(test_block)
|
||||||
|
elif key == "test":
|
||||||
|
teststeps = _load_teststeps(test_block, project_mapping)
|
||||||
|
weight = test_block.pop("weight", 1)
|
||||||
|
for _ in range(weight):
|
||||||
|
tests.append(teststeps)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"config": config,
|
||||||
|
"tests": tests
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,13 +40,10 @@ def gen_locustfile(testcase_file_path):
|
|||||||
"templates",
|
"templates",
|
||||||
"locustfile_template"
|
"locustfile_template"
|
||||||
)
|
)
|
||||||
testcases = loader.load_tests(testcase_file_path)
|
|
||||||
host = testcases[0].get("config", {}).get("request", {}).get("base_url", "")
|
|
||||||
|
|
||||||
with io.open(template_path, encoding='utf-8') as template:
|
with io.open(template_path, encoding='utf-8') as template:
|
||||||
with io.open(locustfile_path, 'w', encoding='utf-8') as locustfile:
|
with io.open(locustfile_path, 'w', encoding='utf-8') as locustfile:
|
||||||
template_content = template.read()
|
template_content = template.read()
|
||||||
template_content = template_content.replace("$HOST", host)
|
|
||||||
template_content = template_content.replace("$TESTCASE_FILE", testcase_file_path)
|
template_content = template_content.replace("$TESTCASE_FILE", testcase_file_path)
|
||||||
locustfile.write(template_content)
|
locustfile.write(template_content)
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,46 @@
|
|||||||
#coding: utf-8
|
import logging
|
||||||
|
import random
|
||||||
|
|
||||||
import zmq
|
import zmq
|
||||||
|
from httprunner.exceptions import MyBaseError, MyBaseFailure
|
||||||
|
from httprunner.loader import load_locust_tests
|
||||||
|
from httprunner.runner import Runner
|
||||||
from locust import HttpLocust, TaskSet, task
|
from locust import HttpLocust, TaskSet, task
|
||||||
from httprunner import LocustRunner
|
from locust.events import request_failure
|
||||||
from httprunner.loader import load_tests
|
|
||||||
|
logging.getLogger().setLevel(logging.CRITICAL)
|
||||||
|
logging.getLogger('locust.main').setLevel(logging.INFO)
|
||||||
|
logging.getLogger('locust.runners').setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
class WebPageTasks(TaskSet):
|
class WebPageTasks(TaskSet):
|
||||||
def on_start(self):
|
def on_start(self):
|
||||||
self.test_runner = LocustRunner(self.client)
|
self.test_runner = Runner(self.locust.config, self.client)
|
||||||
self.testcases = loader.load_tests(self.locust.file_path)
|
self.testcases = load_locust_tests(self.locust.file_path)
|
||||||
|
|
||||||
@task
|
@task(weight=1)
|
||||||
def test_specified_scenario(self):
|
def test_any(self):
|
||||||
self.test_runner.run(self.testcases)
|
teststeps = random.choice(self.locust.tests)
|
||||||
|
for teststep in teststeps:
|
||||||
|
try:
|
||||||
|
self.test_runner.run_test(teststep)
|
||||||
|
except (MyBaseError, MyBaseFailure) as ex:
|
||||||
|
request_failure.fire(
|
||||||
|
request_type=teststep.get("request", {}).get("method"),
|
||||||
|
name=teststep.get("name"),
|
||||||
|
response_time=0,
|
||||||
|
exception=ex
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class WebPageUser(HttpLocust):
|
class WebPageUser(HttpLocust):
|
||||||
host = "$HOST"
|
|
||||||
task_set = WebPageTasks
|
task_set = WebPageTasks
|
||||||
min_wait = 1000
|
min_wait = 10
|
||||||
max_wait = 5000
|
max_wait = 30
|
||||||
|
|
||||||
file_path = "$TESTCASE_FILE"
|
file_path = "$TESTCASE_FILE"
|
||||||
|
locust_tests = load_locust_tests(file_path)
|
||||||
|
config = locust_tests["config"]
|
||||||
|
tests = locust_tests["tests"]
|
||||||
|
|
||||||
|
host = config.get('request', {}).get('base_url', '')
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
- config:
|
||||||
|
name: basic test with httpbin
|
||||||
|
request:
|
||||||
|
base_url: https://httpbin.org/
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: index
|
||||||
|
weight: 5
|
||||||
|
request:
|
||||||
|
url: /
|
||||||
|
method: GET
|
||||||
|
validate:
|
||||||
|
- eq: ["status_code", 200]
|
||||||
|
- contains: [content, "HTTP Request & Response Service"]
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: headers
|
||||||
|
weight: 3
|
||||||
|
request:
|
||||||
|
url: /headers
|
||||||
|
method: GET
|
||||||
|
validate:
|
||||||
|
- eq: ["status_code", 200]
|
||||||
|
- eq: [content.headers.Host, "httpbin.org"]
|
||||||
|
|
||||||
|
- test:
|
||||||
|
name: user-agent
|
||||||
|
weight: 2
|
||||||
|
request:
|
||||||
|
url: /user-agent
|
||||||
|
method: GET
|
||||||
|
validate:
|
||||||
|
- eq: ["status_code", 200]
|
||||||
|
- startswith: [content.user-agent, "python-requests"]
|
||||||
+1
-13
@@ -2,7 +2,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from httprunner import HttpRunner, LocustRunner, api, loader, parser
|
from httprunner import HttpRunner, api, loader, parser
|
||||||
from locust import HttpLocust
|
from locust import HttpLocust
|
||||||
from tests.api_server import HTTPBIN_SERVER
|
from tests.api_server import HTTPBIN_SERVER
|
||||||
from tests.base import ApiServerUnittest
|
from tests.base import ApiServerUnittest
|
||||||
@@ -375,15 +375,3 @@ class TestHttpRunner(ApiServerUnittest):
|
|||||||
os.getcwd(), 'tests/httpbin/basic.yml')
|
os.getcwd(), 'tests/httpbin/basic.yml')
|
||||||
runner = HttpRunner().run(testcase_file_path)
|
runner = HttpRunner().run(testcase_file_path)
|
||||||
self.assertTrue(runner.summary["success"])
|
self.assertTrue(runner.summary["success"])
|
||||||
|
|
||||||
|
|
||||||
class TestLocustRunner(ApiServerUnittest):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
WebPageUser = type('WebPageUser', (HttpLocust,), {})
|
|
||||||
self.locust_client = WebPageUser.client
|
|
||||||
|
|
||||||
def test_LocustRunner(self):
|
|
||||||
testcase_file = os.path.join(os.getcwd(), 'tests', 'httpbin', 'basic.yml')
|
|
||||||
locust_runner = LocustRunner(self.locust_client)
|
|
||||||
locust_runner.run(testcase_file)
|
|
||||||
|
|||||||
+23
-2
@@ -283,8 +283,20 @@ class TestSuiteLoader(unittest.TestCase):
|
|||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
cls.project_mapping = loader.load_project_tests(os.path.join(os.getcwd(), "tests"))
|
cls.project_mapping = loader.load_project_tests(os.path.join(os.getcwd(), "tests"))
|
||||||
|
|
||||||
def test_load_test_file_testcase(self):
|
def test_load_teststeps(self):
|
||||||
testcase = loader._load_test_file("tests/testcases/smoketest.yml", self.project_mapping)
|
test_block = {
|
||||||
|
"name": "setup and reset all.",
|
||||||
|
"suite": "setup_and_reset($device_sn)",
|
||||||
|
"output": ["token", "device_sn"]
|
||||||
|
}
|
||||||
|
teststeps = loader._load_teststeps(test_block, self.project_mapping)
|
||||||
|
self.assertEqual(len(teststeps), 2)
|
||||||
|
self.assertEqual(teststeps[0]["name"], "get token")
|
||||||
|
self.assertEqual(teststeps[1]["name"], "reset all users")
|
||||||
|
|
||||||
|
def test_load_testcase(self):
|
||||||
|
raw_testcase = loader.load_file("tests/testcases/smoketest.yml")
|
||||||
|
testcase = loader._load_testcase(raw_testcase, self.project_mapping)
|
||||||
self.assertEqual(testcase["config"]["name"], "smoketest")
|
self.assertEqual(testcase["config"]["name"], "smoketest")
|
||||||
self.assertIn("device_sn", testcase["config"]["variables"][0])
|
self.assertIn("device_sn", testcase["config"]["variables"][0])
|
||||||
self.assertEqual(len(testcase["teststeps"]), 8)
|
self.assertEqual(len(testcase["teststeps"]), 8)
|
||||||
@@ -541,3 +553,12 @@ class TestSuiteLoader(unittest.TestCase):
|
|||||||
self.assertIn("get_token", project_mapping["def-api"])
|
self.assertIn("get_token", project_mapping["def-api"])
|
||||||
self.assertIn("setup_and_reset", project_mapping["def-testcase"])
|
self.assertIn("setup_and_reset", project_mapping["def-testcase"])
|
||||||
self.assertEqual(project_mapping["env"]["PROJECT_KEY"], "ABCDEFGH")
|
self.assertEqual(project_mapping["env"]["PROJECT_KEY"], "ABCDEFGH")
|
||||||
|
|
||||||
|
def test_load_locust_tests(self):
|
||||||
|
path = os.path.join(
|
||||||
|
os.getcwd(), 'tests/data/demo_locust.yml')
|
||||||
|
locust_tests = loader.load_locust_tests(path)
|
||||||
|
self.assertEqual(locust_tests["config"]["refs"]["env"]["UserName"], "debugtalk")
|
||||||
|
self.assertEqual(len(locust_tests["tests"]), 10)
|
||||||
|
self.assertEqual(locust_tests["tests"][0][0]["name"], "index")
|
||||||
|
self.assertEqual(locust_tests["tests"][9][0]["name"], "user-agent")
|
||||||
|
|||||||
Reference in New Issue
Block a user