refactor: relocate python test files

This commit is contained in:
debugtalk
2022-03-23 17:28:54 +08:00
parent 8ac27790b2
commit 64ff34a341
38 changed files with 127 additions and 43 deletions

View File

@@ -0,0 +1,50 @@
import unittest
from starlette.testclient import TestClient
from httprunner.app.main import app
client = TestClient(app)
class TestDebug(unittest.TestCase):
def test_debug_single_testcase(self):
json_data = {
"project_meta": {
"debugtalk_py": "\ndef hello(name):\n print(f'hello, {name}')\n",
"variables": {},
"env": {},
},
"testcase": {
"config": {
"name": "test demo for debug service",
"verify": False,
"base_url": "",
"variables": {},
"setup_hooks": [],
"teardown_hooks": [],
"export": [],
},
"teststeps": [
{
"name": "get index page",
"request": {
"method": "GET",
"url": "https://httpbin.org/",
"params": {},
"headers": {},
"json": {},
"cookies": {},
"timeout": 30,
"allow_redirects": True,
"verify": False,
},
"extract": {},
"validate": [],
}
],
},
}
response = client.post("/hrun/debug/testcase", json=json_data)
assert response.status_code == 200
assert response.json()["code"] == 0

52
httprunner/cli_test.py Normal file
View File

@@ -0,0 +1,52 @@
import io
import os
import sys
import unittest
import pytest
from httprunner.cli import main
class TestCli(unittest.TestCase):
def setUp(self):
self.captured_output = io.StringIO()
sys.stdout = self.captured_output
def tearDown(self):
sys.stdout = sys.__stdout__ # Reset redirect.
def test_show_version(self):
sys.argv = ["hrun", "-V"]
with self.assertRaises(SystemExit) as cm:
main()
self.assertEqual(cm.exception.code, 0)
from httprunner import __version__
self.assertIn(__version__, self.captured_output.getvalue().strip())
def test_show_help(self):
sys.argv = ["hrun", "-h"]
with self.assertRaises(SystemExit) as cm:
main()
self.assertEqual(cm.exception.code, 0)
from httprunner import __description__
self.assertIn(__description__, self.captured_output.getvalue().strip())
def test_debug_pytest(self):
cwd = os.getcwd()
try:
os.chdir(os.path.join(cwd, "examples", "postman_echo"))
exit_code = pytest.main(
["-s", "request_methods/request_with_testcase_reference_test.py",]
)
self.assertEqual(exit_code, 0)
finally:
os.chdir(cwd)

237
httprunner/compat_test.py Normal file
View File

@@ -0,0 +1,237 @@
import os
import unittest
from httprunner import compat, exceptions, loader
class TestCompat(unittest.TestCase):
def setUp(self):
loader.project_meta = None
def test_convert_variables(self):
raw_variables = [{"var1": 1}, {"var2": "val2"}]
self.assertEqual(
compat.convert_variables(raw_variables, "examples/data/a-b.c/1.yml"),
{"var1": 1, "var2": "val2"},
)
raw_variables = {"var1": 1, "var2": "val2"}
self.assertEqual(
compat.convert_variables(raw_variables, "examples/data/a-b.c/1.yml"),
{"var1": 1, "var2": "val2"},
)
raw_variables = "${get_variables()}"
self.assertEqual(
compat.convert_variables(raw_variables, "examples/data/a-b.c/1.yml"),
{"foo1": "session_bar1"},
)
with self.assertRaises(exceptions.TestCaseFormatError):
raw_variables = [{"var1": 1}, {"var2": "val2", "var3": 3}]
compat.convert_variables(raw_variables, "examples/data/a-b.c/1.yml")
with self.assertRaises(exceptions.TestCaseFormatError):
compat.convert_variables(None, "examples/data/a-b.c/1.yml")
def test_convert_jmespath(self):
self.assertEqual(compat._convert_jmespath("content.abc"), "body.abc")
self.assertEqual(compat._convert_jmespath("json.abc"), "body.abc")
self.assertEqual(
compat._convert_jmespath("headers.Content-Type"), 'headers."Content-Type"'
)
self.assertEqual(
compat._convert_jmespath('headers."Content-Type"'), 'headers."Content-Type"'
)
self.assertEqual(
compat._convert_jmespath("body.data.buildings.0.building_id"),
"body.data.buildings[0].building_id",
)
self.assertEqual(
compat._convert_jmespath("body.users[-1]"),
"body.users[-1]",
)
with self.assertRaises(SystemExit):
compat._convert_jmespath("2.buildings.0.building_id")
def test_convert_extractors(self):
self.assertEqual(
compat._convert_extractors(
[{"varA": "content.varA"}, {"varB": "json.varB"}]
),
{"varA": "body.varA", "varB": "body.varB"},
)
self.assertEqual(
compat._convert_extractors([{"varA": "content.0.varA"}]),
{"varA": "body[0].varA"},
)
self.assertEqual(
compat._convert_extractors({"varA": "content.0.varA"}),
{"varA": "body[0].varA"},
)
def test_convert_validators(self):
self.assertEqual(
compat._convert_validators(
[{"check": "content.abc", "assert": "eq", "expect": 201}]
),
[{"check": "body.abc", "assert": "eq", "expect": 201}],
)
self.assertEqual(
compat._convert_validators([{"eq": ["content.abc", 201]}]),
[{"eq": ["body.abc", 201]}],
)
self.assertEqual(
compat._convert_validators([{"eq": ["content.0.name", 201]}]),
[{"eq": ["body[0].name", 201]}],
)
def test_ensure_testcase_v3_api(self):
api_content = {
"name": "get with params",
"request": {
"method": "GET",
"url": "/get",
"params": {"foo1": "bar1", "foo2": "bar2"},
"headers": {"User-Agent": "HttpRunner/3.0"},
},
"extract": [{"varA": "content.varA"}, {"user_agent": "headers.User-Agent"}],
"validate": [{"eq": ["content.varB", 200]}, {"lt": ["json.0.varC", 0]}],
}
self.assertEqual(
compat.ensure_testcase_v3_api(api_content),
{
"config": {
"name": "get with params",
"export": ["varA", "user_agent"],
},
"teststeps": [
{
"name": "get with params",
"request": {
"method": "GET",
"url": "/get",
"params": {"foo1": "bar1", "foo2": "bar2"},
"headers": {"User-Agent": "HttpRunner/3.0"},
},
"extract": {
"varA": "body.varA",
"user_agent": 'headers."User-Agent"',
},
"validate": [
{"eq": ["body.varB", 200]},
{"lt": ["body[0].varC", 0]},
],
}
],
},
)
def test_ensure_testcase_v3(self):
testcase_content = {
"config": {"name": "xxx", "base_url": "https://httpbin.org"},
"teststeps": [
{
"name": "get with params",
"request": {
"method": "GET",
"url": "/get",
"params": {"foo1": "bar1", "foo2": "bar2"},
"headers": {"User-Agent": "HttpRunner/3.0"},
},
"extract": [
{"varA": "content.varA"},
{"user_agent": "headers.User-Agent"},
],
"validate": [
{"eq": ["content.varB", 200]},
{"lt": ["json.0.varC", 0]},
],
}
],
}
self.assertEqual(
compat.ensure_testcase_v3(testcase_content),
{
"config": {"name": "xxx", "base_url": "https://httpbin.org"},
"teststeps": [
{
"name": "get with params",
"request": {
"method": "GET",
"url": "/get",
"params": {"foo1": "bar1", "foo2": "bar2"},
"headers": {"User-Agent": "HttpRunner/3.0"},
},
"extract": {
"varA": "body.varA",
"user_agent": 'headers."User-Agent"',
},
"validate": [
{"eq": ["body.varB", 200]},
{"lt": ["body[0].varC", 0]},
],
}
],
},
)
def test_ensure_cli_args(self):
args1 = ["examples/postman_echo/request_methods/hardcode.yml", "--failfast"]
self.assertEqual(
compat.ensure_cli_args(args1),
["examples/postman_echo/request_methods/hardcode.yml"],
)
args2 = ["examples/postman_echo/request_methods/hardcode.yml", "--save-tests"]
self.assertEqual(
compat.ensure_cli_args(args2),
["examples/postman_echo/request_methods/hardcode.yml"],
)
self.assertTrue(os.path.isfile("examples/postman_echo/conftest.py"))
args3 = [
"examples/postman_echo/request_methods/hardcode.yml",
"--report-file",
"report.html",
]
self.assertEqual(
compat.ensure_cli_args(args3),
[
"examples/postman_echo/request_methods/hardcode.yml",
"--html",
"report.html",
"--self-contained-html",
],
)
args4 = [
"examples/postman_echo/request_methods/hardcode.yml",
"--failfast",
"--save-tests",
"--report-file",
"report.html",
]
self.assertEqual(
compat.ensure_cli_args(args4),
[
"examples/postman_echo/request_methods/hardcode.yml",
"--html",
"report.html",
"--self-contained-html",
],
)
def test_ensure_file_path(self):
self.assertEqual(
compat.ensure_path_sep("demo\\test.yml"), os.sep.join(["demo", "test.yml"])
)
self.assertEqual(
compat.ensure_path_sep(os.path.join(os.getcwd(), "demo\\test.yml")),
os.path.join(os.getcwd(), os.sep.join(["demo", "test.yml"])),
)
self.assertEqual(
compat.ensure_path_sep("demo/test.yml"), os.sep.join(["demo", "test.yml"])
)
self.assertEqual(
compat.ensure_path_sep(os.path.join(os.getcwd(), "demo/test.yml")),
os.path.join(os.getcwd(), os.sep.join(["demo", "test.yml"])),
)

View File

@@ -0,0 +1,180 @@
import os
from httprunner.ext.har2case.core import HarParser
from httprunner.ext.har2case.utils import load_har_log_entries
from httprunner.ext.har2case.utils_test import TestHar2CaseUtils
class TestHar(TestHar2CaseUtils):
def setUp(self):
self.data_dir = os.path.join(os.getcwd(), "examples", "data", "har2case")
self.har_path = os.path.join(self.data_dir, "demo.har")
self.har_parser = HarParser(self.har_path)
self.profile_path = os.path.join(self.data_dir, "profile.yml")
def test_prepare_teststep(self):
log_entries = load_har_log_entries(self.har_path)
teststep_dict = self.har_parser._prepare_teststep(log_entries[0])
self.assertIn("name", teststep_dict)
self.assertIn("request", teststep_dict)
self.assertIn("validate", teststep_dict)
validators_mapping = {
validator["eq"][0]: validator["eq"][1]
for validator in teststep_dict["validate"]
}
self.assertEqual(validators_mapping["status_code"], 200)
self.assertEqual(validators_mapping["body.IsSuccess"], True)
self.assertEqual(validators_mapping["body.Code"], 200)
self.assertEqual(validators_mapping["body.Message"], None)
def test_prepare_teststeps(self):
teststeps = self.har_parser._prepare_teststeps()
self.assertIsInstance(teststeps, list)
self.assertIn("name", teststeps[0])
self.assertIn("request", teststeps[0])
self.assertIn("validate", teststeps[0])
def test_gen_testcase_yaml(self):
yaml_file = os.path.join(self.data_dir, "demo.yml")
self.har_parser.gen_testcase(file_type="YAML")
self.assertTrue(os.path.isfile(yaml_file))
os.remove(yaml_file)
def test_gen_testcase_json(self):
json_file = os.path.join(self.data_dir, "demo.json")
self.har_parser.gen_testcase(file_type="JSON")
self.assertTrue(os.path.isfile(json_file))
os.remove(json_file)
def test_profile(self):
har_parser = HarParser(self.har_path, profile=self.profile_path)
teststeps = har_parser._prepare_teststeps()
self.assertEqual(
teststeps[0]["request"]["headers"],
{"Content-Type": "application/x-www-form-urlencoded"},
)
self.assertEqual(
teststeps[0]["request"]["cookies"],
{"CASTGC": "TGT"},
)
def test_filter(self):
filter_str = "httprunner"
har_parser = HarParser(self.har_path, filter_str)
teststeps = har_parser._prepare_teststeps()
self.assertEqual(
teststeps[0]["request"]["url"],
"https://httprunner.top/api/v1/Account/Login",
)
filter_str = "debugtalk"
har_parser = HarParser(self.har_path, filter_str)
teststeps = har_parser._prepare_teststeps()
self.assertEqual(teststeps, [])
def test_exclude(self):
exclude_str = "debugtalk"
har_parser = HarParser(self.har_path, exclude_str=exclude_str)
teststeps = har_parser._prepare_teststeps()
self.assertEqual(
teststeps[0]["request"]["url"],
"https://httprunner.top/api/v1/Account/Login",
)
exclude_str = "httprunner"
har_parser = HarParser(self.har_path, exclude_str=exclude_str)
teststeps = har_parser._prepare_teststeps()
self.assertEqual(teststeps, [])
def test_exclude_multiple(self):
exclude_str = "httprunner|v2"
har_parser = HarParser(self.har_path, exclude_str=exclude_str)
teststeps = har_parser._prepare_teststeps()
self.assertEqual(teststeps, [])
exclude_str = "http2|v1"
har_parser = HarParser(self.har_path, exclude_str=exclude_str)
teststeps = har_parser._prepare_teststeps()
self.assertEqual(teststeps, [])
def test_make_request_data_params(self):
testcase_dict = {"name": "", "request": {}, "validate": []}
entry_json = {
"request": {
"method": "POST",
"postData": {
"mimeType": "application/x-www-form-urlencoded; charset=utf-8",
"params": [{"name": "a", "value": 1}, {"name": "b", "value": "2"}],
},
}
}
self.har_parser._make_request_data(testcase_dict, entry_json)
self.assertEqual(testcase_dict["request"]["data"]["a"], 1)
self.assertEqual(testcase_dict["request"]["data"]["b"], "2")
def test_make_request_data_json(self):
testcase_dict = {"name": "", "request": {}, "validate": []}
entry_json = {
"request": {
"method": "POST",
"postData": {
"mimeType": "application/json; charset=utf-8",
"text": '{"a":"1","b":"2"}',
},
}
}
self.har_parser._make_request_data(testcase_dict, entry_json)
self.assertEqual(testcase_dict["request"]["json"], {"a": "1", "b": "2"})
def test_make_request_data_text_empty(self):
testcase_dict = {"name": "", "request": {}, "validate": []}
entry_json = {
"request": {
"method": "POST",
"postData": {"mimeType": "application/json; charset=utf-8", "text": ""},
}
}
self.har_parser._make_request_data(testcase_dict, entry_json)
self.assertEqual(testcase_dict["request"]["data"], "")
def test_make_validate(self):
testcase_dict = {"name": "", "request": {}, "validate": []}
entry_json = {
"request": {},
"response": {
"status": 200,
"headers": [
{
"name": "Content-Type",
"value": "application/json; charset=utf-8",
},
],
"content": {
"size": 71,
"mimeType": "application/json; charset=utf-8",
# raw response content text is application/jose type
"text": "ZXlKaGJHY2lPaUpTVTBFeFh6VWlMQ0psYm1NaU9pSkJNVEk0UTBKRExV",
"encoding": "base64",
},
},
}
self.har_parser._make_validate(testcase_dict, entry_json)
self.assertEqual(testcase_dict["validate"][0], {"eq": ["status_code", 200]})
self.assertEqual(
testcase_dict["validate"][1],
{"eq": ["headers.Content-Type", "application/json; charset=utf-8"]},
)
def test_make_testcase(self):
har_path = os.path.join(
self.data_dir, "demo-quickstart.har"
)
har_parser = HarParser(har_path)
testcase = har_parser._make_testcase()
self.assertIsInstance(testcase, dict)
self.assertIn("config", testcase)
self.assertIn("teststeps", testcase)
self.assertEqual(len(testcase["teststeps"]), 2)

View File

@@ -0,0 +1,59 @@
import json
import os
import unittest
from httprunner.ext.har2case import utils
class TestHar2CaseUtils(unittest.TestCase):
data_dir = os.path.join(os.getcwd(), "examples", "data", "har2case")
@staticmethod
def create_har_file(file_name, content):
file_path = os.path.join(
TestHar2CaseUtils.data_dir, "{}.har".format(file_name)
)
with open(file_path, "w") as f:
f.write(json.dumps(content))
return file_path
def test_load_har_log_entries(self):
har_path = os.path.join(TestHar2CaseUtils.data_dir, "demo.har")
log_entries = utils.load_har_log_entries(har_path)
self.assertIsInstance(log_entries, list)
self.assertIn("request", log_entries[0])
self.assertIn("response", log_entries[0])
def test_load_har_log_key_error(self):
empty_json_file_path = TestHar2CaseUtils.create_har_file(
file_name="empty_json", content={}
)
with self.assertRaises(SystemExit):
utils.load_har_log_entries(empty_json_file_path)
os.remove(empty_json_file_path)
def test_load_har_log_empty_error(self):
empty_file_path = TestHar2CaseUtils.create_har_file(
file_name="empty", content=""
)
with self.assertRaises(SystemExit):
utils.load_har_log_entries(empty_file_path)
os.remove(empty_file_path)
# def test_x_www_form_urlencoded(self):
# origin_dict = {"a":1, "b": "2"}
# self.assertIn("a=1", utils.x_www_form_urlencoded(origin_dict))
# self.assertIn("b=2", utils.x_www_form_urlencoded(origin_dict))
def test_convert_list_to_dict(self):
origin_list = [{"name": "v", "value": "1"}, {"name": "w", "value": "2"}]
self.assertEqual(utils.convert_list_to_dict(origin_list), {"v": "1", "w": "2"})
def test_convert_x_www_form_urlencoded_to_dict(self):
origin_str = "a=1&b=2"
converted_dict = utils.convert_x_www_form_urlencoded_to_dict(origin_str)
self.assertIsInstance(converted_dict, dict)
self.assertEqual(converted_dict["a"], "1")
self.assertEqual(converted_dict["b"], "2")

123
httprunner/loader_test.py Normal file
View File

@@ -0,0 +1,123 @@
import os
import unittest
from httprunner import exceptions, loader
class TestLoader(unittest.TestCase):
def test_load_testcase_file(self):
path = "examples/postman_echo/request_methods/request_with_variables.yml"
testcase_obj = loader.load_testcase_file(path)
self.assertEqual(
testcase_obj.config.name, "request methods testcase with variables"
)
self.assertEqual(len(testcase_obj.teststeps), 4)
def test_load_json_file_file_format_error(self):
json_tmp_file = "tmp.json"
# create empty file
with open(json_tmp_file, "w") as f:
f.write("")
with self.assertRaises(exceptions.FileFormatError):
loader._load_json_file(json_tmp_file)
os.remove(json_tmp_file)
# create empty json file
with open(json_tmp_file, "w") as f:
f.write("{}")
loader._load_json_file(json_tmp_file)
os.remove(json_tmp_file)
# create invalid format json file
with open(json_tmp_file, "w") as f:
f.write("abc")
with self.assertRaises(exceptions.FileFormatError):
loader._load_json_file(json_tmp_file)
os.remove(json_tmp_file)
def test_load_testcases_bad_filepath(self):
testcase_file_path = os.path.join(os.getcwd(), "examples/data/demo")
with self.assertRaises(exceptions.FileNotFound):
loader.load_testcase_file(testcase_file_path)
def test_load_csv_file_one_parameter(self):
csv_file_path = os.path.join(os.getcwd(), "examples/httpbin/user_agent.csv")
csv_content = loader.load_csv_file(csv_file_path)
self.assertEqual(
csv_content,
[
{"user_agent": "iOS/10.1"},
{"user_agent": "iOS/10.2"},
{"user_agent": "iOS/10.3"},
],
)
def test_load_csv_file_multiple_parameters(self):
csv_file_path = os.path.join(os.getcwd(), "examples/httpbin/account.csv")
csv_content = loader.load_csv_file(csv_file_path)
self.assertEqual(
csv_content,
[
{"username": "test1", "password": "111111"},
{"username": "test2", "password": "222222"},
{"username": "test3", "password": "333333"},
],
)
def test_load_folder_files(self):
folder = os.path.join(os.getcwd(), "examples")
file1 = os.path.join(os.getcwd(), "examples", "test_utils.py")
file2 = os.path.join(os.getcwd(), "examples", "httpbin", "hooks.yml")
files = loader.load_folder_files(folder, recursive=False)
self.assertEqual(files, [])
files = loader.load_folder_files(folder)
self.assertIn(file2, files)
self.assertNotIn(file1, files)
files = loader.load_folder_files("not_existed_foulder", recursive=False)
self.assertEqual([], files)
files = loader.load_folder_files(file2, recursive=False)
self.assertEqual([], files)
def test_load_custom_dot_env_file(self):
dot_env_path = os.path.join(os.getcwd(), "examples", "httpbin", "test.env")
env_variables_mapping = loader.load_dot_env_file(dot_env_path)
self.assertIn("PROJECT_KEY", env_variables_mapping)
self.assertEqual(env_variables_mapping["UserName"], "test")
self.assertEqual(
env_variables_mapping["content_type"], "application/json; charset=UTF-8"
)
def test_load_env_path_not_exist(self):
dot_env_path = os.path.join(os.getcwd(), "tests", "data",)
env_variables_mapping = loader.load_dot_env_file(dot_env_path)
self.assertEqual(env_variables_mapping, {})
def test_locate_file(self):
with self.assertRaises(exceptions.FileNotFound):
loader.locate_file(os.getcwd(), "debugtalk.py")
with self.assertRaises(exceptions.FileNotFound):
loader.locate_file("", "debugtalk.py")
start_path = os.path.join(os.getcwd(), "examples", "httpbin")
self.assertEqual(
loader.locate_file(start_path, "debugtalk.py"),
os.path.join(os.getcwd(), "examples", "httpbin", "debugtalk.py"),
)
self.assertEqual(
loader.locate_file("examples/httpbin/", "debugtalk.py"),
os.path.join(os.getcwd(), "examples", "httpbin", "debugtalk.py"),
)
self.assertEqual(
loader.locate_file("examples/httpbin/", "debugtalk.py"),
os.path.join(os.getcwd(), "examples", "httpbin", "debugtalk.py"),
)

246
httprunner/make_test.py Normal file
View File

@@ -0,0 +1,246 @@
import os
import unittest
from httprunner import loader
from httprunner.make import (
main_make,
convert_testcase_path,
pytest_files_made_cache_mapping,
make_config_chain_style,
make_teststep_chain_style,
pytest_files_run_set,
ensure_file_abs_path_valid,
)
class TestMake(unittest.TestCase):
def setUp(self) -> None:
pytest_files_made_cache_mapping.clear()
pytest_files_run_set.clear()
loader.project_meta = None
self.data_dir = os.path.join(os.getcwd(), "examples", "data")
def test_make_testcase(self):
path = ["examples/postman_echo/request_methods/request_with_variables.yml"]
testcase_python_list = main_make(path)
self.assertEqual(
testcase_python_list[0],
os.path.join(
os.getcwd(),
os.path.join(
"examples",
"postman_echo",
"request_methods",
"request_with_variables_test.py",
),
),
)
def test_make_testcase_with_ref(self):
path = [
"examples/postman_echo/request_methods/request_with_testcase_reference.yml"
]
testcase_python_list = main_make(path)
self.assertEqual(len(testcase_python_list), 1)
self.assertIn(
os.path.join(
os.getcwd(),
os.path.join(
"examples",
"postman_echo",
"request_methods",
"request_with_testcase_reference_test.py",
),
),
testcase_python_list,
)
with open(
os.path.join(
"examples",
"postman_echo",
"request_methods",
"request_with_testcase_reference_test.py",
)
) as f:
content = f.read()
self.assertIn(
"""
from request_methods.request_with_functions_test import (
TestCaseRequestWithFunctions as RequestWithFunctions,
)
""",
content,
)
self.assertIn(
".call(RequestWithFunctions)", content,
)
def test_make_testcase_folder(self):
path = ["examples/postman_echo/request_methods/"]
testcase_python_list = main_make(path)
self.assertIn(
os.path.join(
os.getcwd(),
os.path.join(
"examples",
"postman_echo",
"request_methods",
"request_with_functions_test.py",
),
),
testcase_python_list,
)
def test_ensure_file_path_valid(self):
self.assertEqual(
ensure_file_abs_path_valid(
os.path.join(self.data_dir, "a-b.c", "2 3.yml")
),
os.path.join(self.data_dir, "a_b_c", "T2_3.yml"),
)
loader.project_meta = None
self.assertEqual(
ensure_file_abs_path_valid(
os.path.join(os.getcwd(), "examples", "postman_echo", "request_methods")
),
os.path.join(os.getcwd(), "examples", "postman_echo", "request_methods"),
)
loader.project_meta = None
self.assertEqual(
ensure_file_abs_path_valid(os.path.join(os.getcwd(), "pyproject.toml")),
os.path.join(os.getcwd(), "pyproject.toml"),
)
loader.project_meta = None
self.assertEqual(
ensure_file_abs_path_valid(os.getcwd()), os.getcwd(),
)
loader.project_meta = None
self.assertEqual(
ensure_file_abs_path_valid(
os.path.join(self.data_dir, ".csv")
),
os.path.join(self.data_dir, ".csv"),
)
def test_convert_testcase_path(self):
self.assertEqual(
convert_testcase_path(
os.path.join(self.data_dir, "a-b.c", "2 3.yml")
),
(
os.path.join(self.data_dir, "a_b_c", "T2_3_test.py"),
"T23",
),
)
self.assertEqual(
convert_testcase_path(
os.path.join(self.data_dir, "a-b.c", "中文case.yml")
),
(
os.path.join(self.data_dir, "a_b_c", "中文case_test.py"),
"中文Case",
),
)
def test_make_testsuite(self):
path = ["examples/postman_echo/request_methods/demo_testsuite.yml"]
testcase_python_list = main_make(path)
self.assertEqual(len(testcase_python_list), 2)
self.assertIn(
os.path.join(
os.getcwd(),
os.path.join(
"examples",
"postman_echo",
"request_methods",
"demo_testsuite_yml",
"request_with_functions_test.py",
),
),
testcase_python_list,
)
self.assertIn(
os.path.join(
os.getcwd(),
os.path.join(
"examples",
"postman_echo",
"request_methods",
"demo_testsuite_yml",
"request_with_testcase_reference_test.py",
),
),
testcase_python_list,
)
def test_make_config_chain_style(self):
config = {
"name": "request methods testcase: validate with functions",
"variables": {"foo1": "bar1", "foo2": 22},
"base_url": "https://postman_echo.com",
"verify": False,
"path": "examples/postman_echo/request_methods/validate_with_functions_test.py",
}
self.assertEqual(
make_config_chain_style(config),
"""Config("request methods testcase: validate with functions").variables(**{'foo1': 'bar1', 'foo2': 22}).base_url("https://postman_echo.com").verify(False)""",
)
def test_make_teststep_chain_style(self):
step = {
"name": "get with params",
"variables": {"foo1": "bar1", "foo2": 123, "sum_v": "${sum_two(1, 2)}",},
"request": {
"method": "GET",
"url": "/get",
"params": {"foo1": "$foo1", "foo2": "$foo2", "sum_v": "$sum_v"},
"headers": {"User-Agent": "HttpRunner/${get_httprunner_version()}"},
},
"testcase": "CLS_LB(TestCaseDemo)CLS_RB",
"extract": {
"session_foo1": "body.args.foo1",
"session_foo2": "body.args.foo2",
},
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["body.args.sum_v", "3"]},
],
}
teststep_chain_style = make_teststep_chain_style(step)
self.assertEqual(
teststep_chain_style,
"""Step(RunRequest("get with params").with_variables(**{'foo1': 'bar1', 'foo2': 123, 'sum_v': '${sum_two(1, 2)}'}).get("/get").with_params(**{'foo1': '$foo1', 'foo2': '$foo2', 'sum_v': '$sum_v'}).with_headers(**{'User-Agent': 'HttpRunner/${get_httprunner_version()}'}).extract().with_jmespath('body.args.foo1', 'session_foo1').with_jmespath('body.args.foo2', 'session_foo2').validate().assert_equal("status_code", 200).assert_equal("body.args.sum_v", "3"))""",
)
def test_make_requests_with_json_chain_style(self):
step = {
"name": "get with params",
"variables": {
"foo1": "bar1",
"foo2": 123,
"sum_v": "${sum_two(1, 2)}",
"myjson": {"name": "user", "password": "123456"},
},
"request": {
"method": "GET",
"url": "/get",
"params": {"foo1": "$foo1", "foo2": "$foo2", "sum_v": "$sum_v"},
"headers": {"User-Agent": "HttpRunner/${get_httprunner_version()}"},
"json": "$myjson",
},
"testcase": "CLS_LB(TestCaseDemo)CLS_RB",
"extract": {
"session_foo1": "body.args.foo1",
"session_foo2": "body.args.foo2",
},
"validate": [
{"eq": ["status_code", 200]},
{"eq": ["body.args.sum_v", "3"]},
],
}
teststep_chain_style = make_teststep_chain_style(step)
self.assertEqual(
teststep_chain_style,
"""Step(RunRequest("get with params").with_variables(**{'foo1': 'bar1', 'foo2': 123, 'sum_v': '${sum_two(1, 2)}', 'myjson': {'name': 'user', 'password': '123456'}}).get("/get").with_params(**{'foo1': '$foo1', 'foo2': '$foo2', 'sum_v': '$sum_v'}).with_headers(**{'User-Agent': 'HttpRunner/${get_httprunner_version()}'}).with_json("$myjson").extract().with_jmespath('body.args.foo1', 'session_foo1').with_jmespath('body.args.foo2', 'session_foo2').validate().assert_equal("status_code", 200).assert_equal("body.args.sum_v", "3"))""",
)

550
httprunner/parser_test.py Normal file
View File

@@ -0,0 +1,550 @@
import os
import time
import unittest
from httprunner import parser
from httprunner.exceptions import VariableNotFound, FunctionNotFound
from httprunner.loader import load_project_meta
class TestParserBasic(unittest.TestCase):
def test_parse_variables_mapping(self):
variables = {"varA": "$varB", "varB": "$varC", "varC": "123", "a": 1, "b": 2}
parsed_variables = parser.parse_variables_mapping(variables)
print(parsed_variables)
self.assertEqual(parsed_variables["varA"], "123")
self.assertEqual(parsed_variables["varB"], "123")
def test_parse_variables_mapping_exception(self):
variables = {"varA": "$varB", "varB": "$varC", "a": 1, "b": 2}
with self.assertRaises(VariableNotFound):
parser.parse_variables_mapping(variables)
def test_parse_string_value(self):
self.assertEqual(parser.parse_string_value("123"), 123)
self.assertEqual(parser.parse_string_value("12.3"), 12.3)
self.assertEqual(parser.parse_string_value("a123"), "a123")
self.assertEqual(parser.parse_string_value("$var"), "$var")
self.assertEqual(parser.parse_string_value("${func}"), "${func}")
def test_regex_findall_variables(self):
self.assertEqual(parser.regex_findall_variables("$variable"), ["variable"])
self.assertEqual(parser.regex_findall_variables("${variable}123"), ["variable"])
self.assertEqual(parser.regex_findall_variables("/blog/$postid"), ["postid"])
self.assertEqual(
parser.regex_findall_variables("/$var1/$var2"), ["var1", "var2"]
)
self.assertEqual(parser.regex_findall_variables("abc"), [])
self.assertEqual(parser.regex_findall_variables("Z:2>1*0*1+1$a"), ["a"])
self.assertEqual(parser.regex_findall_variables("Z:2>1*0*1+1$$a"), [])
self.assertEqual(parser.regex_findall_variables("Z:2>1*0*1+1$$$a"), ["a"])
self.assertEqual(parser.regex_findall_variables("Z:2>1*0*1+1$$$$a"), [])
self.assertEqual(parser.regex_findall_variables("Z:2>1*0*1+1$$a$b"), ["b"])
self.assertEqual(parser.regex_findall_variables("Z:2>1*0*1+1$$a$$b"), [])
# variable should not start with digit
self.assertEqual(parser.regex_findall_variables("$1a"), [])
self.assertEqual(parser.regex_findall_variables("${1a}"), [])
def test_extract_variables(self):
self.assertEqual(parser.extract_variables("$var"), {"var"})
self.assertEqual(parser.extract_variables("$var123"), {"var123"})
self.assertEqual(parser.extract_variables("$var_name"), {"var_name"})
self.assertEqual(parser.extract_variables("var"), set())
self.assertEqual(parser.extract_variables("a$var"), {"var"})
self.assertEqual(parser.extract_variables("$v ar"), {"v"})
self.assertEqual(parser.extract_variables(" "), set())
self.assertEqual(parser.extract_variables("$abc*"), {"abc"})
self.assertEqual(parser.extract_variables("${func()}"), set())
self.assertEqual(parser.extract_variables("${func(1,2)}"), set())
self.assertEqual(
parser.extract_variables("${gen_md5($TOKEN, $data, $random)}"),
{"TOKEN", "data", "random"},
)
self.assertEqual(parser.extract_variables("Z:2>1*0*1+1$$1"), set())
def test_parse_function_params(self):
self.assertEqual(parser.parse_function_params(""), {"args": [], "kwargs": {}})
self.assertEqual(parser.parse_function_params("5"), {"args": [5], "kwargs": {}})
self.assertEqual(
parser.parse_function_params("1, 2"), {"args": [1, 2], "kwargs": {}}
)
self.assertEqual(
parser.parse_function_params("a=1, b=2"),
{"args": [], "kwargs": {"a": 1, "b": 2}},
)
self.assertEqual(
parser.parse_function_params("a= 1, b =2"),
{"args": [], "kwargs": {"a": 1, "b": 2}},
)
self.assertEqual(
parser.parse_function_params("1, 2, a=3, b=4"),
{"args": [1, 2], "kwargs": {"a": 3, "b": 4}},
)
self.assertEqual(
parser.parse_function_params("$request, 123"),
{"args": ["$request", 123], "kwargs": {}},
)
self.assertEqual(parser.parse_function_params(" "), {"args": [], "kwargs": {}})
self.assertEqual(
parser.parse_function_params("hello world, a=3, b=4"),
{"args": ["hello world"], "kwargs": {"a": 3, "b": 4}},
)
self.assertEqual(
parser.parse_function_params("$request, 12 3"),
{"args": ["$request", "12 3"], "kwargs": {}},
)
def test_extract_functions(self):
self.assertEqual(parser.regex_findall_functions("${func()}"), [("func", "")])
self.assertEqual(parser.regex_findall_functions("${func(5)}"), [("func", "5")])
self.assertEqual(
parser.regex_findall_functions("${func(a=1, b=2)}"), [("func", "a=1, b=2")]
)
self.assertEqual(
parser.regex_findall_functions("${func(1, $b, c=$x, d=4)}"),
[("func", "1, $b, c=$x, d=4")],
)
self.assertEqual(
parser.regex_findall_functions("/api/1000?_t=${get_timestamp()}"),
[("get_timestamp", "")],
)
self.assertEqual(
parser.regex_findall_functions("/api/${add(1, 2)}"), [("add", "1, 2")]
)
self.assertEqual(
parser.regex_findall_functions("/api/${add(1, 2)}?_t=${get_timestamp()}"),
[("add", "1, 2"), ("get_timestamp", "")],
)
self.assertEqual(
parser.regex_findall_functions("abc${func(1, 2, a=3, b=4)}def"),
[("func", "1, 2, a=3, b=4")],
)
def test_parse_data_string_with_variables(self):
variables_mapping = {
"var_1": "abc",
"var_2": "def",
"var_3": 123,
"var_4": {"a": 1},
"var_5": True,
"var_6": None,
}
self.assertEqual(parser.parse_data("$var_1", variables_mapping), "abc")
self.assertEqual(parser.parse_data("${var_1}", variables_mapping), "abc")
self.assertEqual(parser.parse_data("var_1", variables_mapping), "var_1")
self.assertEqual(parser.parse_data("$var_1#XYZ", variables_mapping), "abc#XYZ")
self.assertEqual(
parser.parse_data("${var_1}#XYZ", variables_mapping), "abc#XYZ"
)
self.assertEqual(
parser.parse_data("/$var_1/$var_2/var3", variables_mapping), "/abc/def/var3"
)
self.assertEqual(parser.parse_data("$var_3", variables_mapping), 123)
self.assertEqual(parser.parse_data("$var_4", variables_mapping), {"a": 1})
self.assertEqual(parser.parse_data("$var_5", variables_mapping), True)
self.assertEqual(parser.parse_data("abc$var_5", variables_mapping), "abcTrue")
self.assertEqual(
parser.parse_data("abc$var_4", variables_mapping), "abc{'a': 1}"
)
self.assertEqual(parser.parse_data("$var_6", variables_mapping), None)
with self.assertRaises(VariableNotFound):
parser.parse_data("/api/$SECRET_KEY", variables_mapping)
self.assertEqual(
parser.parse_data(["$var_1", "$var_2"], variables_mapping), ["abc", "def"]
)
self.assertEqual(
parser.parse_data({"$var_1": "$var_2"}, variables_mapping), {"abc": "def"}
)
# format: $var
value = parser.parse_data("ABC$var_1", variables_mapping)
self.assertEqual(value, "ABCabc")
value = parser.parse_data("ABC$var_1$var_3", variables_mapping)
self.assertEqual(value, "ABCabc123")
value = parser.parse_data("ABC$var_1/$var_3", variables_mapping)
self.assertEqual(value, "ABCabc/123")
value = parser.parse_data("ABC$var_1/", variables_mapping)
self.assertEqual(value, "ABCabc/")
value = parser.parse_data("ABC$var_1$", variables_mapping)
self.assertEqual(value, "ABCabc$")
value = parser.parse_data("ABC$var_1/123$var_1/456", variables_mapping)
self.assertEqual(value, "ABCabc/123abc/456")
value = parser.parse_data("ABC$var_1/$var_2/$var_1", variables_mapping)
self.assertEqual(value, "ABCabc/def/abc")
value = parser.parse_data("func1($var_1, $var_3)", variables_mapping)
self.assertEqual(value, "func1(abc, 123)")
# format: ${var}
value = parser.parse_data("ABC${var_1}", variables_mapping)
self.assertEqual(value, "ABCabc")
value = parser.parse_data("ABC${var_1}${var_3}", variables_mapping)
self.assertEqual(value, "ABCabc123")
value = parser.parse_data("ABC${var_1}/${var_3}", variables_mapping)
self.assertEqual(value, "ABCabc/123")
value = parser.parse_data("ABC${var_1}/", variables_mapping)
self.assertEqual(value, "ABCabc/")
value = parser.parse_data("ABC${var_1}123", variables_mapping)
self.assertEqual(value, "ABCabc123")
value = parser.parse_data("ABC${var_1}/123${var_1}/456", variables_mapping)
self.assertEqual(value, "ABCabc/123abc/456")
value = parser.parse_data("ABC${var_1}/${var_2}/${var_1}", variables_mapping)
self.assertEqual(value, "ABCabc/def/abc")
value = parser.parse_data("func1(${var_1}, ${var_3})", variables_mapping)
self.assertEqual(value, "func1(abc, 123)")
def test_parse_data_multiple_identical_variables(self):
variables_mapping = {
"var_1": "abc",
"var_2": "def",
}
self.assertEqual(
parser.parse_data("/$var_1/$var_2/$var_1", variables_mapping),
"/abc/def/abc",
)
variables_mapping = {"userid": 100, "data": 1498}
content = "/users/$userid/training/$data?userId=$userid&data=$data"
self.assertEqual(
parser.parse_data(content, variables_mapping),
"/users/100/training/1498?userId=100&data=1498",
)
variables_mapping = {"user": 100, "userid": 1000, "data": 1498}
content = "/users/$user/$userid/$data?userId=$userid&data=$data"
self.assertEqual(
parser.parse_data(content, variables_mapping),
"/users/100/1000/1498?userId=1000&data=1498",
)
def test_parse_data_string_with_functions(self):
import random
import string
functions_mapping = {
"gen_random_string": lambda str_len: "".join(
random.choice(string.ascii_letters + string.digits)
for _ in range(str_len)
)
}
result = parser.parse_data(
"${gen_random_string(5)}", functions_mapping=functions_mapping
)
self.assertEqual(len(result), 5)
functions_mapping["add_two_nums"] = lambda a, b=1: a + b
self.assertEqual(
parser.parse_data(
"${add_two_nums(1)}", functions_mapping=functions_mapping
),
2,
)
self.assertEqual(
parser.parse_data(
"${add_two_nums(1, 2)}", functions_mapping=functions_mapping
),
3,
)
self.assertEqual(
parser.parse_data(
"/api/${add_two_nums(1, 2)}", functions_mapping=functions_mapping
),
"/api/3",
)
with self.assertRaises(FunctionNotFound):
parser.parse_data("/api/${gen_md5(abc)}")
variables_mapping = {
"var_1": "abc",
"var_2": "def",
"var_3": 123,
"var_4": {"a": 1},
"var_5": True,
"var_6": None,
}
functions_mapping = {"func1": lambda x, y: str(x) + str(y)}
value = parser.parse_data(
"${func1($var_1, $var_3)}", variables_mapping, functions_mapping
)
self.assertEqual(value, "abc123")
value = parser.parse_data(
"ABC${func1($var_1, $var_3)}DE", variables_mapping, functions_mapping
)
self.assertEqual(value, "ABCabc123DE")
value = parser.parse_data(
"ABC${func1($var_1, $var_3)}$var_5", variables_mapping, functions_mapping
)
self.assertEqual(value, "ABCabc123True")
value = parser.parse_data(
"ABC${func1($var_1, $var_3)}DE$var_4", variables_mapping, functions_mapping
)
self.assertEqual(value, "ABCabc123DE{'a': 1}")
value = parser.parse_data(
"ABC$var_5${func1($var_1, $var_3)}", variables_mapping, functions_mapping
)
self.assertEqual(value, "ABCTrueabc123")
value = parser.parse_data(
"ABC${ord(a)}DEF${len(abcd)}", variables_mapping, functions_mapping
)
self.assertEqual(value, "ABC97DEF4")
def test_parse_data_func_var_duplicate(self):
variables_mapping = {
"var_1": "abc",
"var_2": "def",
"var_3": 123,
"var_4": {"a": 1},
"var_5": True,
"var_6": None,
}
functions_mapping = {"func1": lambda x, y: str(x) + str(y)}
value = parser.parse_data(
"ABC${func1($var_1, $var_3)}--${func1($var_1, $var_3)}",
variables_mapping,
functions_mapping,
)
self.assertEqual(value, "ABCabc123--abc123")
value = parser.parse_data(
"ABC${func1($var_1, $var_3)}$var_1", variables_mapping, functions_mapping
)
self.assertEqual(value, "ABCabc123abc")
value = parser.parse_data(
"ABC${func1($var_1, $var_3)}$var_1--${func1($var_1, $var_3)}$var_1",
variables_mapping,
functions_mapping,
)
self.assertEqual(value, "ABCabc123abc--abc123abc")
def test_parse_data_func_abnormal(self):
variables_mapping = {
"var_1": "abc",
"var_2": "def",
"var_3": 123,
"var_4": {"a": 1},
"var_5": True,
"var_6": None,
}
functions_mapping = {"func1": lambda x, y: str(x) + str(y)}
# {
value = parser.parse_data("ABC$var_1{", variables_mapping, functions_mapping)
self.assertEqual(value, "ABCabc{")
value = parser.parse_data(
"{ABC$var_1{}a}", variables_mapping, functions_mapping
)
self.assertEqual(value, "{ABCabc{}a}")
value = parser.parse_data(
"AB{C$var_1{}a}", variables_mapping, functions_mapping
)
self.assertEqual(value, "AB{Cabc{}a}")
# }
value = parser.parse_data("ABC$var_1}", variables_mapping, functions_mapping)
self.assertEqual(value, "ABCabc}")
# $$
value = parser.parse_data("ABC$$var_1{", variables_mapping, functions_mapping)
self.assertEqual(value, "ABC$var_1{")
# $$$
value = parser.parse_data("ABC$$$var_1{", variables_mapping, functions_mapping)
self.assertEqual(value, "ABC$abc{")
# $$$$
value = parser.parse_data("ABC$$$$var_1{", variables_mapping, functions_mapping)
self.assertEqual(value, "ABC$$var_1{")
# ${
value = parser.parse_data("ABC$var_1${", variables_mapping, functions_mapping)
self.assertEqual(value, "ABCabc${")
value = parser.parse_data("ABC$var_1${a", variables_mapping, functions_mapping)
self.assertEqual(value, "ABCabc${a")
# $}
value = parser.parse_data("ABC$var_1$}a", variables_mapping, functions_mapping)
self.assertEqual(value, "ABCabc$}a")
# }{
value = parser.parse_data("ABC$var_1}{a", variables_mapping, functions_mapping)
self.assertEqual(value, "ABCabc}{a")
# {}
value = parser.parse_data("ABC$var_1{}a", variables_mapping, functions_mapping)
self.assertEqual(value, "ABCabc{}a")
def test_parse_data_request(self):
content = {
"request": {
"url": "/api/users/$uid",
"method": "$method",
"headers": {"token": "$token"},
"data": {
"null": None,
"true": True,
"false": False,
"empty_str": "",
"value": "abc${add_one(3)}def",
},
}
}
variables_mapping = {"uid": 1000, "method": "POST", "token": "abc123"}
functions_mapping = {"add_one": lambda x: x + 1}
result = parser.parse_data(content, variables_mapping, functions_mapping)
self.assertEqual("/api/users/1000", result["request"]["url"])
self.assertEqual("abc123", result["request"]["headers"]["token"])
self.assertEqual("POST", result["request"]["method"])
self.assertIsNone(result["request"]["data"]["null"])
self.assertTrue(result["request"]["data"]["true"])
self.assertFalse(result["request"]["data"]["false"])
self.assertEqual("", result["request"]["data"]["empty_str"])
self.assertEqual("abc4def", result["request"]["data"]["value"])
def test_parse_data_testcase(self):
variables = {
"uid": "1000",
"random": "A2dEx",
"authorization": "a83de0ff8d2e896dbd8efb81ba14e17d",
"data": {"name": "user", "password": "123456"},
}
functions = {
"add_two_nums": lambda a, b=1: a + b,
"get_timestamp": lambda: int(time.time() * 1000),
}
testcase_template = {
"url": "http://127.0.0.1:5000/api/users/$uid/${add_two_nums(1,2)}",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"authorization": "$authorization",
"random": "$random",
"sum": "${add_two_nums(1, 2)}",
},
"body": "$data",
}
parsed_testcase = parser.parse_data(testcase_template, variables, functions)
self.assertEqual(
parsed_testcase["url"], "http://127.0.0.1:5000/api/users/1000/3"
)
self.assertEqual(
parsed_testcase["headers"]["authorization"], variables["authorization"]
)
self.assertEqual(parsed_testcase["headers"]["random"], variables["random"])
self.assertEqual(parsed_testcase["body"], variables["data"])
self.assertEqual(parsed_testcase["headers"]["sum"], 3)
def test_parse_parameters_testcase(self):
parameters = {
"user_agent": ["iOS/10.1", "iOS/10.2"],
"username-password": "${parameterize(request_methods/account.csv)}",
"sum": "${calculate_two_nums(1, 2)}",
}
load_project_meta(
os.path.join(
os.path.dirname(os.path.dirname(__file__)),
"examples",
"postman_echo",
"request_methods",
),
)
parsed_params = parser.parse_parameters(parameters)
self.assertEqual(len(parsed_params), 2 * 3 * 2)
self.assertIn(
{
"username": "test1",
"password": "111111",
"user_agent": "iOS/10.1",
"sum": 3,
},
parsed_params,
)
self.assertIn(
{
"username": "test1",
"password": "111111",
"user_agent": "iOS/10.1",
"sum": 1,
},
parsed_params,
)
self.assertIn(
{
"username": "test1",
"password": "111111",
"user_agent": "iOS/10.2",
"sum": 3,
},
parsed_params,
)
self.assertIn(
{
"username": "test1",
"password": "111111",
"user_agent": "iOS/10.2",
"sum": 1,
},
parsed_params,
)
self.assertIn(
{
"username": "test2",
"password": "222222",
"user_agent": "iOS/10.1",
"sum": 3,
},
parsed_params,
)
self.assertIn(
{
"username": "test2",
"password": "222222",
"user_agent": "iOS/10.1",
"sum": 1,
},
parsed_params,
)
self.assertIn(
{
"username": "test2",
"password": "222222",
"user_agent": "iOS/10.2",
"sum": 3,
},
parsed_params,
)
self.assertIn(
{
"username": "test2",
"password": "222222",
"user_agent": "iOS/10.2",
"sum": 1,
},
parsed_params,
)

View File

@@ -0,0 +1,70 @@
import unittest
import requests
from httprunner.response import ResponseObject
class TestResponse(unittest.TestCase):
def setUp(self) -> None:
resp = requests.post(
"https://httpbin.org/anything",
json={
"locations": [
{"name": "Seattle", "state": "WA"},
{"name": "New York", "state": "NY"},
{"name": "Bellevue", "state": "WA"},
{"name": "Olympia", "state": "WA"},
]
},
)
self.resp_obj = ResponseObject(resp)
def test_extract(self):
variables_mapping = {
'body': 'body'
}
functions_mapping = {
'get_name': lambda: 'name',
}
extract_mapping = self.resp_obj.extract(
{
"var_1": "body.json.locations[0]",
"var_2": "body.json.locations[3].name",
"var_3": "$body.json.locations[3].name",
"var_4": "$body.json.locations[3].${get_name()}",
},
variables_mapping=variables_mapping,
functions_mapping=functions_mapping,
)
self.assertEqual(extract_mapping["var_1"], {"name": "Seattle", "state": "WA"})
self.assertEqual(extract_mapping["var_2"], "Olympia")
self.assertEqual(extract_mapping["var_3"], "Olympia")
self.assertEqual(extract_mapping["var_4"], "Olympia")
def test_validate(self):
self.resp_obj.validate(
[
{"eq": ["body.json.locations[0].name", "Seattle"]},
{"eq": ["body.json.locations[0]", {"name": "Seattle", "state": "WA"}]},
],
)
def test_validate_variables(self):
variables_mapping = {"index": 1, "var_empty": ""}
self.resp_obj.validate(
[
{"eq": ["body.json.locations[$index].name", "New York"]},
{"eq": ["$var_empty", ""]},
],
variables_mapping=variables_mapping,
)
def test_validate_functions(self):
variables_mapping = {"index": 1}
functions_mapping = {"get_num": lambda x: x}
self.resp_obj.validate(
[{"eq": ["${get_num(0)}", 0]}, {"eq": ["${get_num($index)}", 1]},],
variables_mapping=variables_mapping,
functions_mapping=functions_mapping,
)

40
httprunner/runner_test.py Normal file
View File

@@ -0,0 +1,40 @@
import os
import unittest
from httprunner import loader
from httprunner.cli import main_run
from httprunner.runner import HttpRunner
class TestHttpRunner(unittest.TestCase):
def setUp(self):
loader.project_meta = None
self.runner = HttpRunner()
def test_run_testcase_by_path_request_only(self):
self.runner.run_path(
"examples/postman_echo/request_methods/request_with_functions.yml"
)
result = self.runner.get_summary()
self.assertTrue(result.success)
self.assertEqual(result.name, "request methods testcase with functions")
self.assertEqual(result.step_datas[0].name, "get with params")
self.assertEqual(len(result.step_datas), 3)
def test_run_testcase_by_path_ref_testcase(self):
self.runner.run_path(
"examples/postman_echo/request_methods/request_with_testcase_reference.yml"
)
result = self.runner.get_summary()
self.assertTrue(result.success)
self.assertEqual(result.name, "request methods testcase: reference testcase")
self.assertEqual(result.step_datas[0].name, "request with functions")
self.assertEqual(len(result.step_datas), 2)
def test_run_testcase_with_abnormal_path(self):
exit_code = main_run(["examples/data/a-b.c/2 3.yml"])
self.assertEqual(exit_code, 0)
self.assertTrue(os.path.exists("examples/data/a_b_c/__init__.py"))
self.assertTrue(os.path.exists("examples/data/debugtalk.py"))
self.assertTrue(os.path.exists("examples/data/a_b_c/T1_test.py"))
self.assertTrue(os.path.exists("examples/data/a_b_c/T2_3_test.py"))

View File

@@ -0,0 +1,29 @@
import os
import shutil
import subprocess
import unittest
import platform
from httprunner.scaffold import create_scaffold
class TestScaffold(unittest.TestCase):
def test_create_scaffold(self):
project_name = "projectABC"
create_scaffold(project_name)
self.assertTrue(os.path.isdir(os.path.join(project_name, "har")))
self.assertTrue(os.path.isdir(os.path.join(project_name, "testcases")))
self.assertTrue(os.path.isdir(os.path.join(project_name, "reports")))
self.assertTrue(os.path.isfile(os.path.join(project_name, "debugtalk.py")))
self.assertTrue(os.path.isfile(os.path.join(project_name, ".env")))
# run demo testcases
try:
if platform.system() == "Windows":
subprocess.check_call(["hrun", project_name], shell=True)
else:
subprocess.check_call(["hrun", project_name])
except subprocess.SubprocessError:
raise
finally:
shutil.rmtree(project_name)

154
httprunner/utils_test.py Normal file
View File

@@ -0,0 +1,154 @@
import decimal
import json
import os
import unittest
from httprunner import loader, utils
from httprunner.utils import (
ExtendJSONEncoder,
merge_variables,
)
class TestUtils(unittest.TestCase):
def test_set_os_environ(self):
self.assertNotIn("abc", os.environ)
variables_mapping = {"abc": "123"}
utils.set_os_environ(variables_mapping)
self.assertIn("abc", os.environ)
self.assertEqual(os.environ["abc"], "123")
def test_validators(self):
from httprunner.builtin import comparators
functions_mapping = loader.load_module_functions(comparators)
functions_mapping["equal"](None, None)
functions_mapping["equal"](1, 1)
functions_mapping["equal"]("abc", "abc")
with self.assertRaises(AssertionError):
functions_mapping["equal"]("123", 123)
functions_mapping["less_than"](1, 2)
functions_mapping["less_or_equals"](2, 2)
functions_mapping["greater_than"](2, 1)
functions_mapping["greater_or_equals"](2, 2)
functions_mapping["not_equal"](123, "123")
functions_mapping["length_equal"]("123", 3)
with self.assertRaises(AssertionError):
functions_mapping["length_equal"]("123", "3")
with self.assertRaises(AssertionError):
functions_mapping["length_equal"]("123", "abc")
functions_mapping["length_greater_than"]("123", 2)
functions_mapping["length_greater_or_equals"]("123", 3)
functions_mapping["contains"]("123abc456", "3ab")
functions_mapping["contains"](["1", "2"], "1")
functions_mapping["contains"]({"a": 1, "b": 2}, "a")
functions_mapping["contained_by"]("3ab", "123abc456")
functions_mapping["contained_by"](0, [0, 200])
functions_mapping["regex_match"]("123abc456", "^123\w+456$")
with self.assertRaises(AssertionError):
functions_mapping["regex_match"]("123abc456", "^12b.*456$")
functions_mapping["startswith"]("abc123", "ab")
functions_mapping["startswith"]("123abc", 12)
functions_mapping["startswith"](12345, 123)
functions_mapping["endswith"]("abc123", 23)
functions_mapping["endswith"]("123abc", "abc")
functions_mapping["endswith"](12345, 45)
functions_mapping["type_match"](580509390, int)
functions_mapping["type_match"](580509390, "int")
functions_mapping["type_match"]([], list)
functions_mapping["type_match"]([], "list")
functions_mapping["type_match"]([1], "list")
functions_mapping["type_match"]({}, "dict")
functions_mapping["type_match"]({"a": 1}, "dict")
functions_mapping["type_match"](None, "None")
functions_mapping["type_match"](None, "NoneType")
functions_mapping["type_match"](None, None)
def test_lower_dict_keys(self):
request_dict = {
"url": "http://127.0.0.1:5000",
"METHOD": "POST",
"Headers": {"Accept": "application/json", "User-Agent": "ios/9.3"},
}
new_request_dict = utils.lower_dict_keys(request_dict)
self.assertIn("method", new_request_dict)
self.assertIn("headers", new_request_dict)
self.assertIn("Accept", new_request_dict["headers"])
self.assertIn("User-Agent", new_request_dict["headers"])
request_dict = "$default_request"
new_request_dict = utils.lower_dict_keys(request_dict)
self.assertEqual("$default_request", request_dict)
request_dict = None
new_request_dict = utils.lower_dict_keys(request_dict)
self.assertEqual(None, request_dict)
def test_print_info(self):
info_mapping = {"a": 1, "t": (1, 2), "b": {"b1": 123}, "c": None, "d": [4, 5]}
utils.print_info(info_mapping)
def test_sort_dict_by_custom_order(self):
self.assertEqual(
list(
utils.sort_dict_by_custom_order(
{"C": 3, "D": 2, "A": 1, "B": 8}, ["A", "D"]
).keys()
),
["A", "D", "C", "B"],
)
def test_safe_dump_json(self):
class A(object):
pass
data = {"a": A(), "b": decimal.Decimal("1.45")}
with self.assertRaises(TypeError):
json.dumps(data)
json.dumps(data, cls=ExtendJSONEncoder)
def test_override_config_variables(self):
step_variables = {"base_url": "$base_url", "foo1": "bar1"}
config_variables = {"base_url": "https://httpbin.org", "foo1": "bar111"}
self.assertEqual(
merge_variables(step_variables, config_variables),
{"base_url": "https://httpbin.org", "foo1": "bar1"},
)
def test_cartesian_product_one(self):
parameters_content_list = [[{"a": 1}, {"a": 2}]]
product_list = utils.gen_cartesian_product(*parameters_content_list)
self.assertEqual(product_list, [{"a": 1}, {"a": 2}])
def test_cartesian_product_multiple(self):
parameters_content_list = [
[{"a": 1}, {"a": 2}],
[{"x": 111, "y": 112}, {"x": 121, "y": 122}],
]
product_list = utils.gen_cartesian_product(*parameters_content_list)
self.assertEqual(
product_list,
[
{"a": 1, "x": 111, "y": 112},
{"a": 1, "x": 121, "y": 122},
{"a": 2, "x": 111, "y": 112},
{"a": 2, "x": 121, "y": 122},
],
)
def test_cartesian_product_empty(self):
parameters_content_list = []
product_list = utils.gen_cartesian_product(*parameters_content_list)
self.assertEqual(product_list, [])