Skip to content

Commit 8608dbf

Browse files
authored
fix: report is not printing the test cases (#545)
1 parent a40b924 commit 8608dbf

6 files changed

Lines changed: 275 additions & 134 deletions

File tree

scanapi/console.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
from rich.console import Console
22

3-
from scanapi.test_status import TestStatus
43
from scanapi.session import session
5-
4+
from scanapi.test_status import TestStatus
65

76
console = Console()
87

@@ -14,15 +13,23 @@ def write_results(results):
1413
None
1514
"""
1615
for r in results:
17-
for test in r["tests_results"]:
18-
if test["status"] is TestStatus.PASSED:
19-
console.print(f"[bright_green] [PASSED] [white]{test['name']}")
20-
if test["status"] == TestStatus.FAILED:
21-
console.print(
22-
f"[bright_red] [FAILED] [white]{test['name']}\n"
23-
f"\t [bright_red]{test['failure']} is false"
24-
)
25-
_write_summary()
16+
write_result(r)
17+
18+
19+
def write_result(result):
20+
"""Print the test result to the console output
21+
22+
Returns:
23+
None
24+
"""
25+
for test in result["tests_results"]:
26+
if test["status"] is TestStatus.PASSED:
27+
console.print(f"[bright_green] [PASSED] [white]{test['name']}")
28+
if test["status"] == TestStatus.FAILED:
29+
console.print(
30+
f"[bright_red] [FAILED] [white]{test['name']}\n"
31+
f"\t [bright_red]{test['failure']} is false"
32+
)
2633

2734

2835
def write_report_path(uri):
@@ -37,7 +44,7 @@ def write_report_path(uri):
3744
)
3845

3946

40-
def _write_summary():
47+
def write_summary():
4148
"""Write tests summary in console
4249
4350
Returns:

scanapi/scan.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import yaml
44

55
from scanapi.config_loader import load_config_file
6-
from scanapi.console import write_results
6+
from scanapi.console import write_results, write_summary
77
from scanapi.errors import (
88
BadConfigurationError,
99
EmptyConfigFileError,
@@ -22,8 +22,6 @@
2222
def scan():
2323
"""Caller function that tries to scans the file and write the report."""
2424
spec_path = settings["spec_path"]
25-
no_report = settings["no_report"]
26-
open_browser = settings["open_browser"]
2725

2826
try:
2927
api_spec = load_config_file(spec_path)
@@ -51,24 +49,40 @@ def scan():
5149
logger.error(error_message)
5250
raise SystemExit(ExitCode.USAGE_ERROR)
5351

54-
write_results(results)
52+
_write(results)
53+
write_summary()
54+
session.exit()
55+
56+
57+
def _write(results):
58+
"""When the user passed the `--no-report` flag: prints the test results to
59+
the console output.
60+
When the user did not pass the `--no_report flag`: writes the results on a
61+
report file and opens it using a browser, if the --browser flag is present.
62+
63+
Returns:
64+
None
65+
"""
66+
no_report = settings["no_report"]
67+
open_browser = settings["open_browser"]
5568

5669
if no_report:
57-
session.exit()
70+
write_results(results)
71+
return
5872

5973
try:
60-
write_report(results, open_browser)
61-
74+
_write_report(results, open_browser)
6275
except (BadConfigurationError, InvalidPythonCodeError) as e:
6376
logger.error(e)
6477
raise SystemExit(ExitCode.USAGE_ERROR)
6578

66-
session.exit()
67-
6879

69-
def write_report(results, open_browser):
80+
def _write_report(results, open_browser):
7081
"""Constructs a Reporter object and calls the write method of Reporter to
7182
push the results to a file.
83+
84+
Returns:
85+
None
7286
"""
7387
reporter = Reporter(settings["output_path"], settings["template"])
7488
reporter.write(results, open_browser)

scanapi/tree/request_node.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import time
22

3-
from scanapi.console import console
3+
from scanapi.console import console, write_result
44
from scanapi.errors import HTTPMethodNotAllowedError
55
from scanapi.hide_utils import hide_sensitive_info
6+
from scanapi.settings import settings
67
from scanapi.test_status import TestStatus
78
from scanapi.tree.testing_node import TestingNode
89
from scanapi.tree.tree_keys import (
@@ -162,7 +163,7 @@ def run(self):
162163

163164
del self.endpoint.spec_vars["response"]
164165

165-
return {
166+
result = {
166167
"response": response,
167168
"tests_results": tests_results,
168169
"no_failure": all(
@@ -172,6 +173,11 @@ def run(self):
172173
"request_node_name": self.name,
173174
}
174175

176+
if not settings["no_report"]:
177+
write_result(result)
178+
179+
return result
180+
175181
def _run_tests(self):
176182
"""Run all tests cases of request node.
177183

tests/unit/test_console.py

Lines changed: 106 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
from unittest.mock import MagicMock
33

44
from pytest import fixture, mark
5-
from scanapi.console import write_report_path, write_results
5+
6+
from scanapi.console import (
7+
write_report_path,
8+
write_result,
9+
write_results,
10+
write_summary,
11+
)
612

713

814
@fixture
@@ -11,49 +17,58 @@ def mocked__console(mocker):
1117

1218

1319
@mark.describe("console")
14-
@mark.describe("write_results")
20+
@mark.describe("write_result")
1521
class TestWriteResults:
1622
@fixture
17-
def mocked__session(self, mocker):
18-
session = MagicMock()
19-
session.errors = 0
20-
session.elapsed_time.return_value = timedelta(seconds=3)
21-
return mocker.patch("scanapi.console.session", session)
23+
def mocked__write_result(self, mocker):
24+
return mocker.patch("scanapi.console.write_result")
2225

23-
@mark.context("when session has successes and no failures")
24-
@mark.it("should write results and write summary")
25-
def test_write_success(self, mocked__console, mocked__session):
26+
@mark.context("when results is empty")
27+
@mark.it("should not call write_result")
28+
def test_should_not_call(self, mocked__write_result):
29+
write_results([])
2630

27-
test_success = {
28-
"name": "should_be_success",
29-
"status": "passed",
30-
"failure": None,
31-
"error": None,
32-
}
33-
fake_results_passed = [
31+
assert not mocked__write_result.called
32+
33+
@mark.context("when results has size 3")
34+
@mark.it("should call write_result 3 times")
35+
def test_should_call_3_times(self, mocked__write_result):
36+
write_results([1, 2, 3])
37+
38+
assert mocked__write_result.call_count == 3
39+
40+
41+
@mark.describe("console")
42+
@mark.describe("write_result")
43+
class TestWriteResult:
44+
@mark.context("when tests results contains one success")
45+
@mark.it("should print the success result")
46+
def test_write_success(self, mocked__console):
47+
48+
tests_results = [
3449
{
35-
"response": "foo",
36-
"tests_results": [test_success],
37-
"no_failure": True,
38-
},
50+
"name": "should_be_success",
51+
"status": "passed",
52+
"failure": None,
53+
"error": None,
54+
}
3955
]
4056

41-
mocked__session.failures = 0
42-
mocked__session.successes = 1
57+
fake_result_passed = {
58+
"tests_results": tests_results,
59+
}
4360

44-
write_results(fake_results_passed)
61+
write_result(fake_result_passed)
4562

4663
mocked__console.print.assert_called_once_with(
4764
"[bright_green] [PASSED] [white]should_be_success"
4865
)
4966

50-
mocked__console.rule.assert_called_once_with(
51-
"[bright_green]1 passed in 3.0s", characters="=",
52-
)
53-
54-
@mark.context("when session has failures")
55-
@mark.it("should write results and write summary")
56-
def test_write_failures(self, mocker, mocked__console, mocked__session):
67+
@mark.context("when tests results contains one success and one failure")
68+
@mark.it(
69+
"should print two lines, one for the success and one for the failure"
70+
)
71+
def test_write_failures(self, mocker, mocked__console):
5772
tests = [
5873
{
5974
"name": "failed_test",
@@ -68,14 +83,12 @@ def test_write_failures(self, mocker, mocked__console, mocked__session):
6883
"error": None,
6984
},
7085
]
71-
fake_results_failed = [
72-
{"response": "foo", "tests_results": tests, "no_failure": True,},
73-
]
7486

75-
mocked__session.failures = 1
76-
mocked__session.successes = 1
87+
fake_result_failed = {
88+
"tests_results": tests,
89+
}
7790

78-
write_results(fake_results_failed)
91+
write_result(fake_result_failed)
7992

8093
calls = [
8194
mocker.call(
@@ -86,33 +99,17 @@ def test_write_failures(self, mocker, mocked__console, mocked__session):
8699

87100
mocked__console.print.assert_has_calls(calls)
88101

89-
mocked__console.rule.assert_called_once_with(
90-
"[bright_green]1 passed, [bright_red]1 failed, [bright_red]0 errors in 3.0s",
91-
characters="=",
92-
style="bright_red",
93-
)
94-
95102
@mark.context("when session has no tests")
96-
@mark.it("should just write summary")
97-
def test_write_without_tests(
98-
self, mocker, mocked__console, mocked__session
99-
):
100-
101-
fake_results_failed = [
102-
{"response": "foo", "tests_results": [], "no_failure": True,},
103-
]
104-
105-
mocked__session.failures = 0
106-
mocked__session.successes = 0
103+
@mark.it("should print nothing")
104+
def test_write_without_tests(self, mocked__console):
105+
fake_result_failed = {
106+
"tests_results": [],
107+
}
107108

108-
write_results(fake_results_failed)
109+
write_result(fake_result_failed)
109110

110111
assert not mocked__console.print.called
111112

112-
mocked__console.rule.assert_called_once_with(
113-
"[bright_green]0 passed in 3.0s", characters="=",
114-
)
115-
116113

117114
@mark.describe("console")
118115
@mark.describe("write_report_path")
@@ -126,3 +123,53 @@ def test(self, mocked__console):
126123
"The documentation was generated successfully.\n"
127124
"It is available at -> [deep_sky_blue1 underline]http://localhost:8080\n"
128125
)
126+
127+
128+
@mark.describe("console")
129+
@mark.describe("write_summary")
130+
class TestWriteSummary:
131+
@fixture
132+
def mocked__session(self, mocker):
133+
session = MagicMock()
134+
session.errors = 0
135+
session.elapsed_time.return_value = timedelta(seconds=3)
136+
return mocker.patch("scanapi.console.session", session)
137+
138+
@mark.context("when session has successes and no failures")
139+
@mark.it("should print the success summary")
140+
def test_write_success(self, mocked__console, mocked__session):
141+
mocked__session.failures = 0
142+
mocked__session.successes = 1
143+
144+
write_summary()
145+
146+
mocked__console.rule.assert_called_once_with(
147+
"[bright_green]1 passed in 3.0s", characters="=",
148+
)
149+
150+
@mark.context("when session has failures")
151+
@mark.it("should print the failure summary")
152+
def test_write_failures(self, mocked__console, mocked__session):
153+
mocked__session.failures = 1
154+
mocked__session.successes = 1
155+
156+
write_summary()
157+
158+
mocked__console.rule.assert_called_once_with(
159+
"[bright_green]1 passed, [bright_red]1 failed, [bright_red]0 errors in 3.0s",
160+
characters="=",
161+
style="bright_red",
162+
)
163+
164+
@mark.context("when session has no tests")
165+
@mark.it("should print the success summary")
166+
def test_write_without_tests(self, mocked__console, mocked__session):
167+
168+
mocked__session.failures = 0
169+
mocked__session.successes = 0
170+
171+
write_summary()
172+
173+
mocked__console.rule.assert_called_once_with(
174+
"[bright_green]0 passed in 3.0s", characters="=",
175+
)

0 commit comments

Comments
 (0)