Skip to content

Commit

Permalink
attach log stdout stderr (via allure-framework#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sup3rGeo authored and sseliverstov committed Sep 28, 2018
1 parent 6791574 commit 8f98c1b
Show file tree
Hide file tree
Showing 8 changed files with 365 additions and 1 deletion.
8 changes: 7 additions & 1 deletion allure-pytest/src/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from allure_commons.model2 import Parameter
from allure_commons.model2 import Label, Link
from allure_commons.model2 import Status
from allure_commons.types import LabelType
from allure_commons.types import LabelType, AttachmentType
from allure_pytest.utils import allure_description, allure_description_html
from allure_pytest.utils import allure_labels, allure_links, pytest_markers
from allure_pytest.utils import allure_full_name, allure_package, allure_name
Expand Down Expand Up @@ -185,6 +185,12 @@ def pytest_runtest_makereport(self, item, call):
test_result.status = status
test_result.statusDetails = status_details

if self.config.option.attach_capture:
# Capture at teardown contains data from whole test (setup, call, teardown)
self.attach_data(report.caplog, "log", AttachmentType.TEXT, None)
self.attach_data(report.capstdout, "stdout", AttachmentType.TEXT, None)
self.attach_data(report.capstderr, "stderr", AttachmentType.TEXT, None)

uuid = self._cache.pop(item.nodeid)
self.allure_logger.close_test(uuid)

Expand Down
5 changes: 5 additions & 0 deletions allure-pytest/src/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ def pytest_addoption(parser):
dest="clean_alluredir",
help="Clean alluredir folder if it exists")

parser.getgroup("reporting").addoption('--allure-no-capture',
action="store_false",
dest="attach_capture",
help="Do not attach pytest captured logging/stdout/stderr to report")

def label_type(type_name, legal_values=set()):
def a_label_type(string):
atoms = set(string.split(','))
Expand Down
154 changes: 154 additions & 0 deletions allure-pytest/test/capture_integration/test_attach_capture.py.off
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import logging
import pytest


logger = logging.getLogger(__name__)


@pytest.fixture
def fix1():
# Just for checking capture in fixtures
print("fix setup")
logger.info("fix setup")
yield
logger.info("fix teardown")
print("fix teardown")


### These tests really need to be parametrized, how to do it with doctest? ###


def test_capture_stdout_logs_fd(fix1):
"""
>>> import os
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO')

>>> attachment_names = []

>>> test = None
>>> for item in allure_report.test_cases:
... if item["name"] == "test_capture_stdout_logs_fd":
... test = item

>>> for attachment in test["attachments"]:
... name = attachment["name"]
... source = os.path.join(allure_report.result_dir, attachment["source"])
... attachment_names.append(name)
... if name == "stdout":
... with open(source, "r") as f:
... capstdout = f.read()
... assert "fix setup" in capstdout
... assert "begin test" in capstdout
... assert "end test" in capstdout
... assert "fix teardown" in capstdout
... elif name == "log":
... with open(source, "r") as f:
... caplog = f.read()
... assert "fix setup" in caplog
... assert "something in test" in caplog
... assert "fix teardown" in caplog

>>> assert "stdout" in attachment_names
>>> assert "stderr" in attachment_names
>>> assert "log" in attachment_names
"""
print("begin test")
logger.info("something in test")
print("end test")


def test_capture_stdout_no_logs(fix1):
"""
>>> import os
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '-p no:logging')

>>> attachment_names = []

>>> test = None
>>> for item in allure_report.test_cases:
... if item["name"] == "test_capture_stdout_no_logs":
... test = item

>>> for attachment in test["attachments"]:
... name = attachment["name"]
... source = os.path.join(allure_report.result_dir, attachment["source"])
... attachment_names.append(name)
... if name == "stdout":
... with open(source, "r") as f:
... capstdout = f.read()
... assert "fix setup" in capstdout
... assert "begin test" in capstdout
... assert "end test" in capstdout
... assert "fix teardown" in capstdout
... elif name == "log":
... with open(source, "r") as f:
... caplog = f.read()
... assert caplog == ""

>>> assert "stdout" in attachment_names
>>> assert "stderr" in attachment_names
>>> assert "log" in attachment_names
"""
print("begin test")
logger.info("something in test")
print("end test")


def test_capture_stdout_logs_sys(fix1):
"""
>>> import os
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '--capture=sys')

>>> attachment_names = []

>>> test = None
>>> for item in allure_report.test_cases:
... if item["name"] == "test_capture_stdout_logs_sys":
... test = item

>>> with open("DOCTDEBUG", "w") as file:
... a = file.write("{{{}}}\\n{{{}}}".format(test.keys(), test))

>>> for attachment in test["attachments"]:
... name = attachment["name"]
... source = os.path.join(allure_report.result_dir, attachment["source"])
... attachment_names.append(name)
... if name == "stdout":
... with open(source, "r") as f:
... capstdout = f.read()
... assert "fix setup" in capstdout
... assert "begin test" in capstdout
... assert "end test" in capstdout
... assert "fix teardown" in capstdout
... elif name == "log":
... with open(source, "r") as f:
... caplog = f.read()
... assert "fix setup" in caplog
... assert "something in test" in caplog
... assert "fix teardown" in caplog

>>> assert "stdout" in attachment_names
>>> assert "stderr" in attachment_names
>>> assert "log" in attachment_names
"""
print("begin test")
logger.info("something in test")
print("end test")


def test_capture_disabled(fix1):
"""
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '--allure-no-capture')

>>> attachment_names = []

>>> test = None
>>> for item in allure_report.test_cases:
... if item["name"] == "test_capture_disabled":
... test = item

>>> assert "attachments" not in test
"""
print("begin test")
logger.info("something in test")
print("end test")
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import logging
import pytest


logger = logging.getLogger(__name__)


@pytest.fixture
def fix1():
# Just for checking capture in fixtures
print("fix setup")
logger.info("fix setup")
yield
logger.info("fix teardown")
print("fix teardown")


def test_capture_disabled(fix1):
"""
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '--allure-no-capture')
>>> attachment_names = []
>>> test = None
>>> for item in allure_report.test_cases:
... if item["name"] == "test_capture_disabled":
... test = item
>>> assert "attachments" not in test
"""
print("begin test")
logger.info("something in test")
print("end test")
55 changes: 55 additions & 0 deletions allure-pytest/test/capture_integration/test_attach_capture_fd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import logging
import pytest


logger = logging.getLogger(__name__)


@pytest.fixture
def fix1():
# Just for checking capture in fixtures
print("fix setup")
logger.info("fix setup")
yield
logger.info("fix teardown")
print("fix teardown")


def test_capture_stdout_logs_fd(fix1):
"""
>>> import os
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO')
>>> attachment_names = []
>>> test = None
>>> for item in allure_report.test_cases:
... if item["name"] == "test_capture_stdout_logs_fd":
... test = item
>>> for attachment in test["attachments"]:
... name = attachment["name"]
... source = os.path.join(allure_report.result_dir, attachment["source"])
... attachment_names.append(name)
... if name == "stdout":
... with open(source, "r") as f:
... capstdout = f.read()
... assert "fix setup" in capstdout
... assert "begin test" in capstdout
... assert "end test" in capstdout
... assert "fix teardown" in capstdout
... elif name == "log":
... with open(source, "r") as f:
... caplog = f.read()
... assert "fix setup" in caplog
... assert "something in test" in caplog
... assert "fix teardown" in caplog
>>> assert "stdout" in attachment_names
>>> assert "stderr" in attachment_names
>>> assert "log" in attachment_names
"""
print("begin test")
logger.info("something in test")
print("end test")

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import logging
import pytest


logger = logging.getLogger(__name__)


@pytest.fixture
def fix1():
# Just for checking capture in fixtures
print("fix setup")
logger.info("fix setup")
yield
logger.info("fix teardown")
print("fix teardown")


def test_capture_stdout_no_logs(fix1):
"""
>>> import os
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '-p no:logging')
>>> attachment_names = []
>>> test = None
>>> for item in allure_report.test_cases:
... if item["name"] == "test_capture_stdout_no_logs":
... test = item
>>> for attachment in test["attachments"]:
... name = attachment["name"]
... source = os.path.join(allure_report.result_dir, attachment["source"])
... attachment_names.append(name)
... if name == "stdout":
... with open(source, "r") as f:
... capstdout = f.read()
... assert "fix setup" in capstdout
... assert "begin test" in capstdout
... assert "end test" in capstdout
... assert "fix teardown" in capstdout
... elif name == "log":
... with open(source, "r") as f:
... caplog = f.read()
... assert caplog == ""
>>> assert "stdout" in attachment_names
>>> assert "stderr" in attachment_names
>>> assert "log" in attachment_names
"""
print("begin test")
logger.info("something in test")
print("end test")

57 changes: 57 additions & 0 deletions allure-pytest/test/capture_integration/test_attach_capture_sys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import logging
import pytest


logger = logging.getLogger(__name__)


@pytest.fixture
def fix1():
# Just for checking capture in fixtures
print("fix setup")
logger.info("fix setup")
yield
logger.info("fix teardown")
print("fix teardown")


def test_capture_stdout_logs_sys(fix1):
"""
>>> import os
>>> allure_report = getfixture('allure_report_with_params')('--log-cli-level=INFO', '--capture=sys')
>>> attachment_names = []
>>> test = None
>>> for item in allure_report.test_cases:
... if item["name"] == "test_capture_stdout_logs_sys":
... test = item
>>> with open("DOCTDEBUG", "w") as file:
... a = file.write("{{{}}}\\n{{{}}}".format(test.keys(), test))
>>> for attachment in test["attachments"]:
... name = attachment["name"]
... source = os.path.join(allure_report.result_dir, attachment["source"])
... attachment_names.append(name)
... if name == "stdout":
... with open(source, "r") as f:
... capstdout = f.read()
... assert "fix setup" in capstdout
... assert "begin test" in capstdout
... assert "end test" in capstdout
... assert "fix teardown" in capstdout
... elif name == "log":
... with open(source, "r") as f:
... caplog = f.read()
... assert "fix setup" in caplog
... assert "something in test" in caplog
... assert "fix teardown" in caplog
>>> assert "stdout" in attachment_names
>>> assert "stderr" in attachment_names
>>> assert "log" in attachment_names
"""
print("begin test")
logger.info("something in test")
print("end test")
1 change: 1 addition & 0 deletions allure-python-commons-test/src/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@

class AllureReport(object):
def __init__(self, result):
self.result_dir = result
self.test_cases = [json.load(item) for item in self._report_items(result, '*result.json')]
self.test_containers = [json.load(item) for item in self._report_items(result, '*container.json')]
self.attachments = [item.read() for item in self._report_items(result, '*attachment.*')]
Expand Down

0 comments on commit 8f98c1b

Please sign in to comment.