Skip to content

Commit f4e592e

Browse files
Sup3rGeosseliverstov
authored andcommitted
attach log stdout stderr (via #285)
1 parent ddc7f5c commit f4e592e

File tree

8 files changed

+365
-1
lines changed

8 files changed

+365
-1
lines changed

allure-pytest/src/listener.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from allure_commons.model2 import Parameter
1515
from allure_commons.model2 import Label, Link
1616
from allure_commons.model2 import Status
17-
from allure_commons.types import LabelType
17+
from allure_commons.types import LabelType, AttachmentType
1818
from allure_pytest.utils import allure_description, allure_description_html
1919
from allure_pytest.utils import allure_labels, allure_links, pytest_markers
2020
from allure_pytest.utils import allure_full_name, allure_package, allure_name
@@ -185,6 +185,12 @@ def pytest_runtest_makereport(self, item, call):
185185
test_result.status = status
186186
test_result.statusDetails = status_details
187187

188+
if self.config.option.attach_capture:
189+
# Capture at teardown contains data from whole test (setup, call, teardown)
190+
self.attach_data(report.caplog, "log", AttachmentType.TEXT, None)
191+
self.attach_data(report.capstdout, "stdout", AttachmentType.TEXT, None)
192+
self.attach_data(report.capstderr, "stderr", AttachmentType.TEXT, None)
193+
188194
uuid = self._cache.pop(item.nodeid)
189195
self.allure_logger.close_test(uuid)
190196

allure-pytest/src/plugin.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ def pytest_addoption(parser):
2424
dest="clean_alluredir",
2525
help="Clean alluredir folder if it exists")
2626

27+
parser.getgroup("reporting").addoption('--allure-no-capture',
28+
action="store_false",
29+
dest="attach_capture",
30+
help="Do not attach pytest captured logging/stdout/stderr to report")
31+
2732
def label_type(type_name, legal_values=set()):
2833
def a_label_type(string):
2934
atoms = set(string.split(','))
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import logging
2+
import pytest
3+
4+
5+
logger = logging.getLogger(__name__)
6+
7+
8+
@pytest.fixture
9+
def fix1():
10+
# Just for checking capture in fixtures
11+
print("fix setup")
12+
logger.info("fix setup")
13+
yield
14+
logger.info("fix teardown")
15+
print("fix teardown")
16+
17+
18+
### These tests really need to be parametrized, how to do it with doctest? ###
19+
20+
21+
def test_capture_stdout_logs_fd(fix1):
22+
"""
23+
>>> import os
24+
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO')
25+
26+
>>> attachment_names = []
27+
28+
>>> test = None
29+
>>> for item in allure_report.test_cases:
30+
... if item["name"] == "test_capture_stdout_logs_fd":
31+
... test = item
32+
33+
>>> for attachment in test["attachments"]:
34+
... name = attachment["name"]
35+
... source = os.path.join(allure_report.result_dir, attachment["source"])
36+
... attachment_names.append(name)
37+
... if name == "stdout":
38+
... with open(source, "r") as f:
39+
... capstdout = f.read()
40+
... assert "fix setup" in capstdout
41+
... assert "begin test" in capstdout
42+
... assert "end test" in capstdout
43+
... assert "fix teardown" in capstdout
44+
... elif name == "log":
45+
... with open(source, "r") as f:
46+
... caplog = f.read()
47+
... assert "fix setup" in caplog
48+
... assert "something in test" in caplog
49+
... assert "fix teardown" in caplog
50+
51+
>>> assert "stdout" in attachment_names
52+
>>> assert "stderr" in attachment_names
53+
>>> assert "log" in attachment_names
54+
"""
55+
print("begin test")
56+
logger.info("something in test")
57+
print("end test")
58+
59+
60+
def test_capture_stdout_no_logs(fix1):
61+
"""
62+
>>> import os
63+
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '-p no:logging')
64+
65+
>>> attachment_names = []
66+
67+
>>> test = None
68+
>>> for item in allure_report.test_cases:
69+
... if item["name"] == "test_capture_stdout_no_logs":
70+
... test = item
71+
72+
>>> for attachment in test["attachments"]:
73+
... name = attachment["name"]
74+
... source = os.path.join(allure_report.result_dir, attachment["source"])
75+
... attachment_names.append(name)
76+
... if name == "stdout":
77+
... with open(source, "r") as f:
78+
... capstdout = f.read()
79+
... assert "fix setup" in capstdout
80+
... assert "begin test" in capstdout
81+
... assert "end test" in capstdout
82+
... assert "fix teardown" in capstdout
83+
... elif name == "log":
84+
... with open(source, "r") as f:
85+
... caplog = f.read()
86+
... assert caplog == ""
87+
88+
>>> assert "stdout" in attachment_names
89+
>>> assert "stderr" in attachment_names
90+
>>> assert "log" in attachment_names
91+
"""
92+
print("begin test")
93+
logger.info("something in test")
94+
print("end test")
95+
96+
97+
def test_capture_stdout_logs_sys(fix1):
98+
"""
99+
>>> import os
100+
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '--capture=sys')
101+
102+
>>> attachment_names = []
103+
104+
>>> test = None
105+
>>> for item in allure_report.test_cases:
106+
... if item["name"] == "test_capture_stdout_logs_sys":
107+
... test = item
108+
109+
>>> with open("DOCTDEBUG", "w") as file:
110+
... a = file.write("{{{}}}\\n{{{}}}".format(test.keys(), test))
111+
112+
>>> for attachment in test["attachments"]:
113+
... name = attachment["name"]
114+
... source = os.path.join(allure_report.result_dir, attachment["source"])
115+
... attachment_names.append(name)
116+
... if name == "stdout":
117+
... with open(source, "r") as f:
118+
... capstdout = f.read()
119+
... assert "fix setup" in capstdout
120+
... assert "begin test" in capstdout
121+
... assert "end test" in capstdout
122+
... assert "fix teardown" in capstdout
123+
... elif name == "log":
124+
... with open(source, "r") as f:
125+
... caplog = f.read()
126+
... assert "fix setup" in caplog
127+
... assert "something in test" in caplog
128+
... assert "fix teardown" in caplog
129+
130+
>>> assert "stdout" in attachment_names
131+
>>> assert "stderr" in attachment_names
132+
>>> assert "log" in attachment_names
133+
"""
134+
print("begin test")
135+
logger.info("something in test")
136+
print("end test")
137+
138+
139+
def test_capture_disabled(fix1):
140+
"""
141+
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '--allure-no-capture')
142+
143+
>>> attachment_names = []
144+
145+
>>> test = None
146+
>>> for item in allure_report.test_cases:
147+
... if item["name"] == "test_capture_disabled":
148+
... test = item
149+
150+
>>> assert "attachments" not in test
151+
"""
152+
print("begin test")
153+
logger.info("something in test")
154+
print("end test")
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import logging
2+
import pytest
3+
4+
5+
logger = logging.getLogger(__name__)
6+
7+
8+
@pytest.fixture
9+
def fix1():
10+
# Just for checking capture in fixtures
11+
print("fix setup")
12+
logger.info("fix setup")
13+
yield
14+
logger.info("fix teardown")
15+
print("fix teardown")
16+
17+
18+
def test_capture_disabled(fix1):
19+
"""
20+
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '--allure-no-capture')
21+
22+
>>> attachment_names = []
23+
24+
>>> test = None
25+
>>> for item in allure_report.test_cases:
26+
... if item["name"] == "test_capture_disabled":
27+
... test = item
28+
29+
>>> assert "attachments" not in test
30+
"""
31+
print("begin test")
32+
logger.info("something in test")
33+
print("end test")
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import logging
2+
import pytest
3+
4+
5+
logger = logging.getLogger(__name__)
6+
7+
8+
@pytest.fixture
9+
def fix1():
10+
# Just for checking capture in fixtures
11+
print("fix setup")
12+
logger.info("fix setup")
13+
yield
14+
logger.info("fix teardown")
15+
print("fix teardown")
16+
17+
18+
def test_capture_stdout_logs_fd(fix1):
19+
"""
20+
>>> import os
21+
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO')
22+
23+
>>> attachment_names = []
24+
25+
>>> test = None
26+
>>> for item in allure_report.test_cases:
27+
... if item["name"] == "test_capture_stdout_logs_fd":
28+
... test = item
29+
30+
>>> for attachment in test["attachments"]:
31+
... name = attachment["name"]
32+
... source = os.path.join(allure_report.result_dir, attachment["source"])
33+
... attachment_names.append(name)
34+
... if name == "stdout":
35+
... with open(source, "r") as f:
36+
... capstdout = f.read()
37+
... assert "fix setup" in capstdout
38+
... assert "begin test" in capstdout
39+
... assert "end test" in capstdout
40+
... assert "fix teardown" in capstdout
41+
... elif name == "log":
42+
... with open(source, "r") as f:
43+
... caplog = f.read()
44+
... assert "fix setup" in caplog
45+
... assert "something in test" in caplog
46+
... assert "fix teardown" in caplog
47+
48+
>>> assert "stdout" in attachment_names
49+
>>> assert "stderr" in attachment_names
50+
>>> assert "log" in attachment_names
51+
"""
52+
print("begin test")
53+
logger.info("something in test")
54+
print("end test")
55+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import logging
2+
import pytest
3+
4+
5+
logger = logging.getLogger(__name__)
6+
7+
8+
@pytest.fixture
9+
def fix1():
10+
# Just for checking capture in fixtures
11+
print("fix setup")
12+
logger.info("fix setup")
13+
yield
14+
logger.info("fix teardown")
15+
print("fix teardown")
16+
17+
18+
def test_capture_stdout_no_logs(fix1):
19+
"""
20+
>>> import os
21+
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '-p no:logging')
22+
23+
>>> attachment_names = []
24+
25+
>>> test = None
26+
>>> for item in allure_report.test_cases:
27+
... if item["name"] == "test_capture_stdout_no_logs":
28+
... test = item
29+
30+
>>> for attachment in test["attachments"]:
31+
... name = attachment["name"]
32+
... source = os.path.join(allure_report.result_dir, attachment["source"])
33+
... attachment_names.append(name)
34+
... if name == "stdout":
35+
... with open(source, "r") as f:
36+
... capstdout = f.read()
37+
... assert "fix setup" in capstdout
38+
... assert "begin test" in capstdout
39+
... assert "end test" in capstdout
40+
... assert "fix teardown" in capstdout
41+
... elif name == "log":
42+
... with open(source, "r") as f:
43+
... caplog = f.read()
44+
... assert caplog == ""
45+
46+
>>> assert "stdout" in attachment_names
47+
>>> assert "stderr" in attachment_names
48+
>>> assert "log" in attachment_names
49+
"""
50+
print("begin test")
51+
logger.info("something in test")
52+
print("end test")
53+
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import logging
2+
import pytest
3+
4+
5+
logger = logging.getLogger(__name__)
6+
7+
8+
@pytest.fixture
9+
def fix1():
10+
# Just for checking capture in fixtures
11+
print("fix setup")
12+
logger.info("fix setup")
13+
yield
14+
logger.info("fix teardown")
15+
print("fix teardown")
16+
17+
18+
def test_capture_stdout_logs_sys(fix1):
19+
"""
20+
>>> import os
21+
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '--capture=sys')
22+
23+
>>> attachment_names = []
24+
25+
>>> test = None
26+
>>> for item in allure_report.test_cases:
27+
... if item["name"] == "test_capture_stdout_logs_sys":
28+
... test = item
29+
30+
>>> with open("DOCTDEBUG", "w") as file:
31+
... a = file.write("{{{}}}\\n{{{}}}".format(test.keys(), test))
32+
33+
>>> for attachment in test["attachments"]:
34+
... name = attachment["name"]
35+
... source = os.path.join(allure_report.result_dir, attachment["source"])
36+
... attachment_names.append(name)
37+
... if name == "stdout":
38+
... with open(source, "r") as f:
39+
... capstdout = f.read()
40+
... assert "fix setup" in capstdout
41+
... assert "begin test" in capstdout
42+
... assert "end test" in capstdout
43+
... assert "fix teardown" in capstdout
44+
... elif name == "log":
45+
... with open(source, "r") as f:
46+
... caplog = f.read()
47+
... assert "fix setup" in caplog
48+
... assert "something in test" in caplog
49+
... assert "fix teardown" in caplog
50+
51+
>>> assert "stdout" in attachment_names
52+
>>> assert "stderr" in attachment_names
53+
>>> assert "log" in attachment_names
54+
"""
55+
print("begin test")
56+
logger.info("something in test")
57+
print("end test")

allure-python-commons-test/src/report.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383

8484
class AllureReport(object):
8585
def __init__(self, result):
86+
self.result_dir = result
8687
self.test_cases = [json.load(item) for item in self._report_items(result, '*result.json')]
8788
self.test_containers = [json.load(item) for item in self._report_items(result, '*container.json')]
8889
self.attachments = [item.read() for item in self._report_items(result, '*attachment.*')]

0 commit comments

Comments
 (0)