refactor: remove unused code

This commit is contained in:
debugtalk
2020-05-15 22:23:16 +08:00
parent 9a299f618d
commit fe32e8441a
11 changed files with 11 additions and 1016 deletions
-20
View File
@@ -1,20 +0,0 @@
"""
HttpRunner report
- summarize: aggregate test stat data to summary
- stringify: stringify summary, in order to dump json file and generate html report.
- html: render html report
"""
from httprunner.report.summarize import get_platform, aggregate_stat, get_summary
from httprunner.report.stringify import stringify_summary
from httprunner.report.html import HtmlTestResult, gen_html_report
__all__ = [
"get_platform",
"aggregate_stat",
"get_summary",
"stringify_summary",
"HtmlTestResult",
"gen_html_report",
]
-12
View File
@@ -1,12 +0,0 @@
"""
HttpRunner html report
- result: define resultclass for unittest TextTestRunner
- gen_report: render html report with jinja2 template
"""
from httprunner.report.html.result import HtmlTestResult
from httprunner.report.html.gen_report import gen_html_report
__all__ = ["HtmlTestResult", "gen_html_report"]
-64
View File
@@ -1,64 +0,0 @@
import io
import os
from jinja2 import Template
from loguru import logger
from httprunner.exceptions import SummaryEmpty
from httprunner.schema import TestSuiteSummary
def gen_html_report(
testsuite_summary: TestSuiteSummary,
report_template=None,
report_dir=None,
report_file=None,
):
""" render html report with specified report name and template
Args:
testsuite_summary (dict): testsuite result summary data
report_template (str): specify html report template path, template should be in Jinja2 format.
report_dir (str): specify html report save directory
report_file (str): specify html report file path, this has higher priority than specifying report dir.
"""
if testsuite_summary.stat.total == 0:
logger.error(f"test result testsuite_summary is empty ! {testsuite_summary}")
raise SummaryEmpty
if not report_template:
report_template = os.path.join(
os.path.abspath(os.path.dirname(__file__)), "template.html"
)
logger.debug("No html report template specified, use default.")
else:
logger.info(f"render with html report template: {report_template}")
logger.info("Start to render Html report ...")
if report_file:
report_dir = os.path.dirname(report_file)
report_file_name = os.path.basename(report_file)
else:
report_dir = report_dir or os.path.join(os.getcwd(), "reports")
# fix #826: Windows does not support file name include ":"
report_file_name = "{}.html".format(
testsuite_summary.time.start_at_iso_format.replace(":", "").replace("-", "")
)
if not os.path.isdir(report_dir):
os.makedirs(report_dir)
report_path = os.path.join(report_dir, report_file_name)
with io.open(report_template, "r", encoding="utf-8") as fp_r:
template_content = fp_r.read()
with io.open(report_path, "w", encoding="utf-8") as fp_w:
rendered_content = Template(
template_content, extensions=["jinja2.ext.loopcontrols"]
).render(testsuite_summary.dict())
fp_w.write(rendered_content)
logger.info(f"Generated Html report: {report_path}")
return report_path
-65
View File
@@ -1,65 +0,0 @@
import time
import unittest
from loguru import logger
class HtmlTestResult(unittest.TextTestResult):
""" A html result class that can generate formatted html results, used by TextTestRunner.
Each testcase is corresponding to one HtmlTestResult instance
"""
def __init__(self, stream, descriptions, verbosity):
super(HtmlTestResult, self).__init__(stream, descriptions, verbosity)
self.name = ""
self.status = ""
self.attachment = ""
self.step_datas = None
def _record_test(self, test, status, attachment=""):
self.name = test.shortDescription()
self.status = status
self.attachment = attachment
self.step_datas = test.step_datas
def startTestRun(self):
self.start_at = time.time()
def startTest(self, test):
""" add start test time """
super(HtmlTestResult, self).startTest(test)
logger.info(test.shortDescription())
def addSuccess(self, test):
super(HtmlTestResult, self).addSuccess(test)
self._record_test(test, "success")
print("")
def addError(self, test, err):
super(HtmlTestResult, self).addError(test, err)
self._record_test(test, "error", self._exc_info_to_string(err, test))
print("")
def addFailure(self, test, err):
super(HtmlTestResult, self).addFailure(test, err)
self._record_test(test, "failure", self._exc_info_to_string(err, test))
print("")
def addSkip(self, test, reason):
super(HtmlTestResult, self).addSkip(test, reason)
self._record_test(test, "skipped", reason)
print("")
def addExpectedFailure(self, test, err):
super(HtmlTestResult, self).addExpectedFailure(test, err)
self._record_test(test, "ExpectedFailure", self._exc_info_to_string(err, test))
print("")
def addUnexpectedSuccess(self, test):
super(HtmlTestResult, self).addUnexpectedSuccess(test)
self._record_test(test, "UnexpectedSuccess")
print("")
@property
def duration(self):
return time.time() - self.start_at
-350
View File
@@ -1,350 +0,0 @@
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{html_report_name}} - 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: {{html_report_name}}</h1>
<h2>Summary</h2>
<table id="summary">
<tr>
<th>START AT</th>
<td colspan="4">{{time.start_at_iso_format}}</td>
</tr>
<tr>
<th>DURATION</th>
<td colspan="4">{{ '%0.3f'| format(time.duration|float) }} seconds</td>
</tr>
<tr>
<th>PLATFORM</th>
<td>HttpRunner {{ platform.httprunner_version }} </td>
<td>{{ platform.python_version }} </td>
<td colspan="2">{{ platform.platform }}</td>
</tr>
<tr>
<th>STAT</th>
<th colspan="2">SUCCESS</th>
<th colspan="2">FAIL</th>
</tr>
<tr>
<td>total (details) =></td>
<td colspan="2">{{stat.success}}</td>
<td colspan="2">{{stat.fail}}</td>
</tr>
</table>
<h2>Details</h2>
{% for testcase_summary in testcases %}
{% set testcase_index = loop.index %}
<h3>{{testcase_summary.name}}</h3>
<table id="testcase_{{testcase_index}}" class="details">
<tr>
<th>Status</th>
<th colspan="2">Name</th>
<th>Response Time</th>
<th>Detail</th>
</tr>
{% set testcase = testcase_summary %}
{% set step_datas = testcase_summary.step_datas %}
{% for session_data in step_datas %}
{% set step_index = "{}_{}".format(testcase_index, loop.index) %}
<tr id="step_{{step_index}}">
<th class="{{session_data.status}}" style="width:5em;">{{session_data.status}}</th>
<td colspan="2">{{session_data.name}}</td>
<td style="text-align:center;width:6em;">{{ session_data.stat.response_time_ms }} ms</td>
<td class="detail">
<a class="button" href="#popup_log_{{step_index}}">log-{{loop.index}}</a>
<div id="popup_log_{{step_index}}" class="overlay">
<div class="popup">
<h2>Request and Response data</h2>
<a class="close" href="#step_{{step_index}}">&times;</a>
<div class="content">
<h3>Name: {{ session_data.name }}</h3>
{% for req_resp in session_data.req_resps %}
{% if loop.index > 1 %}
<div class="separator">==================================== redirect to ====================================</div>
{% endif %}
<h3>Request:</h3>
<div style="overflow: auto">
<table>
{% for key, value in req_resp.request.items() %}
<tr>
<th>{{key}}</th>
<td>
{% if key in ["headers", "body"] %}
<pre>{{ value | e }}</pre>
{% else %}
{{value}}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
<h3>Response:</h3>
<div style="overflow: auto">
<table>
{% for key, value in req_resp.response.items() %}
<tr>
<th>{{key}}</th>
<td>
{% if key == "headers" %}
<pre>{{ value | e }}</pre>
{% elif key == "body" %}
{% if "image" in req_resp.response.content_type %}
<img src="{{ req_resp.response.content }}" />
{% else %}
<pre>{{ value | e }}</pre>
{% endif %}
{% else %}
{{ value }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
<h3>Validators:</h3>
<div style="overflow: auto">
{% set validate_extractors = session_data.validators.validate_extractor %}
{% if validate_extractors %}
<table>
<tr>
<th>check</th>
<th>comparator</th>
<th>expect value</th>
<th>actual value</th>
</tr>
{% for validator in validate_extractors %}
<tr>
{% if validator.check_result == "pass" %}
<td class="passed">
{% elif validator.check_result == "fail" %}
<td class="failed">
{% elif validator.check_result == "unchecked" %}
<td class="unchecked">
{% endif %}
{{validator.check | e}}
</td>
<td>{{validator.comparator}}</td>
<td>{{validator.expect | e}}</td>
<td>{{validator.check_value | e}}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% set validate_script = session_data.validators.validate_script %}
{% if validate_script %}
<table>
<tr>
<th>validate script</th><th>output</th>
</tr>
<tr>
<td><pre>{{validate_script.validate_script | safe}}</pre></td>
{% if validate_script.check_result == "pass" %}
<td class="passed">
{% elif validate_script.check_result == "fail" %}
<td class="failed">
{% endif %}
{{validate_script.output}}
</td>
</tr>
</table>
{% endif %}
</div>
<h3>Statistics:</h3>
<div style="overflow: auto">
<table>
<tr>
<th>content_size(bytes)</th>
<td>{{ session_data.stat.content_size }}</td>
</tr>
<tr>
<th>response_time(ms)</th>
<td>{{ session_data.stat.response_time_ms }}</td>
</tr>
<tr>
<th>elapsed(ms)</th>
<td>{{ session_data.stat.elapsed_ms }}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
{% if session_data.status == "failed" %}
<a class="button" href="#popup_attachment_{{step_index}}">traceback</a>
<div id="popup_attachment_{{step_index}}" class="overlay">
<div class="popup">
<h2>Traceback Message</h2>
<a class="close" href="#step_{{step_index}}">&times;</a>
<div class="content"><pre>{{ testcase.attachment | e }}</pre></div>
</div>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endfor %}
</body>
-45
View File
@@ -1,45 +0,0 @@
import json
import platform
import time
import uuid
import requests
from httprunner import __version__
def prepare_event_kwargs(event_name, params):
""" prepare report event kwargs"""
kwargs = {
"headers": {"content-type": "application/json"},
"json": {
"user": {"user_unique_id": str(uuid.getnode())},
"header": {
"app_id": 173519,
"os_name": platform.system(),
"os_version": platform.release(),
"app_version": __version__, # HttpRunner version
},
"events": [
{
"event": event_name,
"params": json.dumps(params),
"time": int(time.time()),
}
],
"verbose": 1,
},
}
return kwargs
def report_event(event_name, success=True):
params = {"success": 1 if success else 0}
kwargs = prepare_event_kwargs(event_name, params)
resp = requests.post("http://mcs.snssdk.com/v1/json", **kwargs)
print("resp---", resp.json())
if __name__ == "__main__":
report_event("loader")
-170
View File
@@ -1,170 +0,0 @@
import json
from base64 import b64encode
from collections import Iterable
from typing import List
from jinja2 import escape
from requests.cookies import RequestsCookieJar
from httprunner.schema import TestSuiteSummary, SessionData
def dumps_json(value):
""" dumps json value to indented string
Args:
value (dict): raw json data
Returns:
str: indented json dump string
"""
return json.dumps(value, indent=2, ensure_ascii=False)
def detect_encoding(value):
try:
return json.detect_encoding(value)
except AttributeError:
return "utf-8"
def __stringify_request(request_data):
""" stringfy HTTP request data
Args:
request_data (dict): HTTP request data in dict.
{
"url": "http://127.0.0.1:5000/api/get-token",
"method": "POST",
"headers": {
"User-Agent": "python-requests/2.20.0",
"Accept-Encoding": "gzip, deflate",
"Accept": "*/*",
"Connection": "keep-alive",
"user_agent": "iOS/10.3",
"device_sn": "TESTCASE_CREATE_XXX",
"os_platform": "ios",
"app_version": "2.8.6",
"Content-Type": "application/json",
"Content-Length": "52"
},
"body": b'{"sign": "cb9d60acd09080ea66c8e63a1c78c6459ea00168"}',
"verify": false
}
"""
for key, value in request_data.items():
if isinstance(value, (list, dict)):
value = dumps_json(value)
elif isinstance(value, bytes):
try:
encoding = detect_encoding(value)
value = value.decode(encoding)
if key == "body":
try:
# request body is in json format
value = json.loads(value)
value = dumps_json(value)
except json.JSONDecodeError:
pass
value = escape(value)
except UnicodeDecodeError:
pass
elif not isinstance(value, (str, bytes, int, float, Iterable)):
# class instance, e.g. MultipartEncoder()
value = repr(value)
elif isinstance(value, RequestsCookieJar):
value = value.get_dict()
request_data[key] = value
def __stringify_response(response_data):
""" stringfy HTTP response data
Args:
response_data (dict):
{
"status_code": 404,
"headers": {
"Content-Type": "application/json",
"Content-Length": "30",
"Server": "Werkzeug/0.14.1 Python/3.7.0",
"Date": "Tue, 27 Nov 2018 06:19:27 GMT"
},
"encoding": "None",
"content_type": "application/json",
"ok": false,
"url": "http://127.0.0.1:5000/api/users/9001",
"reason": "NOT FOUND",
"cookies": {},
"body": {
"success": false,
"data": {}
}
}
"""
for key, value in response_data.items():
if isinstance(value, (list, dict)):
value = dumps_json(value)
elif isinstance(value, bytes):
try:
encoding = response_data.get("encoding")
if not encoding or encoding == "None":
encoding = detect_encoding(value)
if key == "body" and "image" in response_data["content_type"]:
# display image
value = "data:{};base64,{}".format(
response_data["content_type"], b64encode(value).decode(encoding)
)
else:
value = escape(value.decode(encoding))
except UnicodeDecodeError:
pass
elif not isinstance(value, (str, bytes, int, float, Iterable)):
# class instance, e.g. MultipartEncoder()
value = repr(value)
elif isinstance(value, RequestsCookieJar):
value = value.get_dict()
response_data[key] = value
def stringify_summary(testsuite_summary: TestSuiteSummary):
""" stringify summary, in order to dump json file and generate html report.
"""
for index, testcase_summary in enumerate(testsuite_summary.testcases):
if not testcase_summary.name:
testcase_summary.name = f"testcase {index}"
step_datas = testcase_summary.step_datas
for step_data in step_datas:
if isinstance(step_data.data, list):
# List[SessionData]
session_data_list: List[SessionData] = step_data.data
for session_data in session_data_list:
req_resp_list = session_data.req_resps
for req_resp in req_resp_list:
__stringify_request(req_resp.request)
__stringify_response(req_resp.response)
else:
# SessionData
session_data: SessionData = step_data.data
req_resp_list = session_data.req_resps
for req_resp in req_resp_list:
__stringify_request(req_resp.request)
__stringify_response(req_resp.response)
-76
View File
@@ -1,76 +0,0 @@
import platform
from datetime import datetime
from httprunner import __version__
from httprunner.report.html.result import HtmlTestResult
from httprunner.schema import TestCaseSummary, TestCaseTime, TestCaseInOut
def get_platform():
return {
"httprunner_version": __version__,
"python_version": "{} {}".format(
platform.python_implementation(), platform.python_version()
),
"platform": platform.platform(),
}
def aggregate_stat(origin_stat, new_stat):
""" aggregate new_stat to origin_stat.
Args:
origin_stat (dict): origin stat dict, will be updated with new_stat dict.
new_stat (dict): new stat dict.
"""
for key in new_stat:
if key not in origin_stat:
origin_stat[key] = new_stat[key]
elif key == "start_at":
# start datetime
origin_stat["start_at"] = min(origin_stat["start_at"], new_stat["start_at"])
elif key == "duration":
# duration = max_end_time - min_start_time
max_end_time = max(
origin_stat["start_at"] + origin_stat["duration"],
new_stat["start_at"] + new_stat["duration"],
)
min_start_time = min(origin_stat["start_at"], new_stat["start_at"])
origin_stat["duration"] = max_end_time - min_start_time
else:
origin_stat[key] += new_stat[key]
def get_summary(result: HtmlTestResult) -> TestCaseSummary:
""" get summary from test result
Args:
result (instance): HtmlTestResult() instance
Returns:
dict: summary extracted from result.
{
"success": True,
"stat": {},
"time": {},
"record": {}
}
"""
start_at_timestamp = result.start_at
start_at_iso_format = datetime.utcfromtimestamp(start_at_timestamp).isoformat()
return TestCaseSummary(
success=result.wasSuccessful(),
time=TestCaseTime(
start_at=result.start_at,
start_at_iso_format=start_at_iso_format,
duration=result.duration,
),
name=result.name,
status=result.status,
attachment=result.attachment,
in_out=TestCaseInOut(),
step_datas=result.step_datas,
)
+1 -1
View File
@@ -174,7 +174,7 @@ class HttpRunner(object):
self.start_at = time.time() self.start_at = time.time()
self.step_datas: List[StepData] = [] self.step_datas: List[StepData] = []
self.session_variables.clear() self.session_variables = {}
for step in self.teststeps: for step in self.teststeps:
# update with config variables # update with config variables
step.variables.update(self.config.variables) step.variables.update(self.config.variables)
+10 -144
View File
@@ -1,15 +1,11 @@
# encoding: utf-8
import collections import collections
import copy
import io
import itertools
import json import json
import os.path import os.path
from typing import Union import platform
from loguru import logger from loguru import logger
from httprunner import __version__
from httprunner import exceptions from httprunner import exceptions
@@ -83,42 +79,6 @@ def lower_dict_keys(origin_dict):
return {key.lower(): value for key, value in origin_dict.items()} return {key.lower(): value for key, value in origin_dict.items()}
def deepcopy_dict(data):
""" deepcopy dict data, ignore file object (_io.BufferedReader)
Args:
data (dict): dict data structure
{
'a': 1,
'b': [2, 4],
'c': lambda x: x+1,
'd': open('LICENSE'),
'f': {
'f1': {'a1': 2},
'f2': io.open('LICENSE', 'rb'),
}
}
Returns:
dict: deep copied dict data, with file object unchanged.
"""
try:
return copy.deepcopy(data)
except TypeError:
copied_data = {}
for key, value in data.items():
if isinstance(value, dict):
copied_data[key] = deepcopy_dict(value)
else:
try:
copied_data[key] = copy.deepcopy(value)
except TypeError:
copied_data[key] = value
return copied_data
def print_info(info_mapping): def print_info(info_mapping):
""" print info in mapping. """ print info in mapping.
@@ -164,47 +124,6 @@ def print_info(info_mapping):
logger.info(content) logger.info(content)
def gen_cartesian_product(*args):
""" generate cartesian product for lists
Args:
args (list of list): lists to be generated with cartesian product
Returns:
list: cartesian product in list
Examples:
>>> arg1 = [{"a": 1}, {"a": 2}]
>>> arg2 = [{"x": 111, "y": 112}, {"x": 121, "y": 122}]
>>> args = [arg1, arg2]
>>> gen_cartesian_product(*args)
>>> # same as below
>>> gen_cartesian_product(arg1, arg2)
[
{'a': 1, 'x': 111, 'y': 112},
{'a': 1, 'x': 121, 'y': 122},
{'a': 2, 'x': 111, 'y': 112},
{'a': 2, 'x': 121, 'y': 122}
]
"""
if not args:
return []
elif len(args) == 1:
return args[0]
product_list = []
for product_item_tuple in itertools.product(*args):
product_item_dict = {}
for item in product_item_tuple:
product_item_dict.update(item)
product_list.append(product_item_dict)
return product_list
def omit_long_data(body, omit_len=512): def omit_long_data(body, omit_len=512):
""" omit too long str/bytes """ omit too long str/bytes
""" """
@@ -224,64 +143,11 @@ def omit_long_data(body, omit_len=512):
return omitted_body + appendix_str return omitted_body + appendix_str
def dump_json_file(json_data: Union[dict, list], json_file_abs_path: str) -> None: def get_platform():
""" dump json data to file return {
""" "httprunner_version": __version__,
"python_version": "{} {}".format(
class PythonObjectEncoder(json.JSONEncoder): platform.python_implementation(), platform.python_version()
def default(self, obj): ),
try: "platform": platform.platform(),
return super().default(self, obj) }
except TypeError:
return str(obj)
file_foder_path = os.path.dirname(json_file_abs_path)
if not os.path.isdir(file_foder_path):
os.makedirs(file_foder_path)
try:
with io.open(json_file_abs_path, "w", encoding="utf-8") as outfile:
json.dump(
json_data,
outfile,
indent=4,
separators=(",", ":"),
ensure_ascii=False,
cls=PythonObjectEncoder,
)
msg = f"dump file: {json_file_abs_path}"
logger.info(msg)
except TypeError as ex:
msg = f"Failed to dump json file: {json_file_abs_path}\nReason: {ex}"
logger.error(msg)
def prepare_log_file_abs_path(test_path: str, file_name: str) -> str:
""" prepare dump json file absolute path.
"""
current_working_dir = os.getcwd()
if not test_path:
# running passed in testcase/testsuite data structure
dump_file_name = f"tests_mapping.{file_name}"
dumped_json_file_abs_path = os.path.join(
current_working_dir, "logs", dump_file_name
)
return dumped_json_file_abs_path
# both test_path and pwd_dir_path are absolute path
logs_dir_path = os.path.join(current_working_dir, "logs")
if os.path.isdir(test_path):
file_foder_path = os.path.join(logs_dir_path, test_path)
dump_file_name = f"all.{file_name}"
else:
file_relative_folder_path, test_file = os.path.split(test_path)
file_foder_path = os.path.join(logs_dir_path, file_relative_folder_path)
test_file_name, _file_suffix = os.path.splitext(test_file)
dump_file_name = f"{test_file_name}.{file_name}"
dumped_json_file_abs_path = os.path.join(file_foder_path, dump_file_name)
return dumped_json_file_abs_path
-69
View File
@@ -86,75 +86,6 @@ class TestUtils(unittest.TestCase):
new_request_dict = utils.lower_dict_keys(request_dict) new_request_dict = utils.lower_dict_keys(request_dict)
self.assertEqual(None, request_dict) self.assertEqual(None, request_dict)
def test_deepcopy_dict(self):
license_path = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "LICENSE"
)
data = {
"a": 1,
"b": [2, 4],
"c": lambda x: x + 1,
"d": open(license_path),
"f": {"f1": {"a1": 2}, "f2": io.open(license_path, "rb"),},
}
new_data = utils.deepcopy_dict(data)
data["a"] = 0
self.assertEqual(new_data["a"], 1)
data["f"]["f1"] = 123
self.assertEqual(new_data["f"]["f1"], {"a1": 2})
self.assertNotEqual(id(new_data["b"]), id(data["b"]))
self.assertEqual(id(new_data["c"]), id(data["c"]))
# self.assertEqual(id(new_data["d"]), id(data["d"]))
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, [])
def test_print_info(self): def test_print_info(self):
info_mapping = {"a": 1, "t": (1, 2), "b": {"b1": 123}, "c": None, "d": [4, 5]} info_mapping = {"a": 1, "t": (1, 2), "b": {"b1": 123}, "c": None, "d": [4, 5]}
utils.print_info(info_mapping) utils.print_info(info_mapping)
def test_prepare_dump_json_file_path_for_folder(self):
# hrun tests/httpbin/a.b.c/ --save-tests
test_path = os.path.join("tests", "httpbin", "a.b.c")
self.assertEqual(
utils.prepare_log_file_abs_path(test_path, "loaded.json"),
os.path.join(os.getcwd(), "logs", "tests/httpbin/a.b.c/all.loaded.json"),
)
def test_prepare_dump_json_file_path_for_file(self):
# hrun tests/httpbin/a.b.c/rpc.yml --save-tests
test_path = os.path.join("tests", "httpbin", "a.b.c", "rpc.yml")
self.assertEqual(
utils.prepare_log_file_abs_path(test_path, "loaded.json"),
os.path.join(os.getcwd(), "logs", "tests/httpbin/a.b.c/rpc.loaded.json"),
)
def test_prepare_dump_json_file_path_for_passed_testcase(self):
test_path = ""
self.assertEqual(
utils.prepare_log_file_abs_path(test_path, "loaded.json"),
os.path.join(os.getcwd(), "logs", "tests_mapping.loaded.json"),
)