2018-10-25 15:01:29 +08:00
|
|
|
from __future__ import absolute_import
|
|
|
|
from __future__ import division
|
|
|
|
from __future__ import print_function
|
|
|
|
|
2009-09-06 22:59:39 +08:00
|
|
|
import os
|
2015-11-27 22:43:01 +08:00
|
|
|
|
|
|
|
import py
|
2018-10-25 15:01:29 +08:00
|
|
|
|
|
|
|
import _pytest._code
|
2015-11-27 22:43:01 +08:00
|
|
|
import pytest
|
2018-10-25 15:01:29 +08:00
|
|
|
from _pytest.nodes import FSCollector
|
|
|
|
from _pytest.nodes import Item
|
|
|
|
from _pytest.nodes import Node
|
|
|
|
from _pytest.resultlog import generic_path
|
|
|
|
from _pytest.resultlog import pytest_configure
|
|
|
|
from _pytest.resultlog import pytest_unconfigure
|
|
|
|
from _pytest.resultlog import ResultLog
|
2015-11-27 22:43:01 +08:00
|
|
|
|
2009-09-06 22:59:39 +08:00
|
|
|
|
2018-09-02 08:58:48 +08:00
|
|
|
pytestmark = pytest.mark.filterwarnings("ignore:--result-log is deprecated")
|
|
|
|
|
|
|
|
|
2009-12-30 23:18:59 +08:00
|
|
|
def test_generic_path(testdir):
|
2010-12-06 23:54:42 +08:00
|
|
|
from _pytest.main import Session
|
2018-05-23 22:48:46 +08:00
|
|
|
|
2010-01-03 08:02:44 +08:00
|
|
|
config = testdir.parseconfig()
|
2010-11-07 17:19:58 +08:00
|
|
|
session = Session(config)
|
2018-05-23 22:48:46 +08:00
|
|
|
p1 = Node("a", config=config, session=session, nodeid="a")
|
2017-07-17 07:25:09 +08:00
|
|
|
# assert p1.fspath is None
|
2018-05-23 22:48:46 +08:00
|
|
|
p2 = Node("B", parent=p1)
|
|
|
|
p3 = Node("()", parent=p2)
|
|
|
|
item = Item("c", parent=p3)
|
2009-09-06 22:59:39 +08:00
|
|
|
|
|
|
|
res = generic_path(item)
|
2018-05-23 22:48:46 +08:00
|
|
|
assert res == "a.B().c"
|
2009-09-06 22:59:39 +08:00
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
p0 = FSCollector("proj/test", config=config, session=session)
|
|
|
|
p1 = FSCollector("proj/test/a", parent=p0)
|
|
|
|
p2 = Node("B", parent=p1)
|
|
|
|
p3 = Node("()", parent=p2)
|
|
|
|
p4 = Node("c", parent=p3)
|
|
|
|
item = Item("[1]", parent=p4)
|
2009-09-06 22:59:39 +08:00
|
|
|
|
|
|
|
res = generic_path(item)
|
2018-05-23 22:48:46 +08:00
|
|
|
assert res == "test/a:B().c[1]"
|
2009-09-06 22:59:39 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2009-09-06 22:59:39 +08:00
|
|
|
def test_write_log_entry():
|
2009-09-17 21:31:35 +08:00
|
|
|
reslog = ResultLog(None, None)
|
2009-09-06 22:59:39 +08:00
|
|
|
reslog.logfile = py.io.TextIO()
|
2018-05-23 22:48:46 +08:00
|
|
|
reslog.write_log_entry("name", ".", "")
|
2009-09-06 22:59:39 +08:00
|
|
|
entry = reslog.logfile.getvalue()
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry[-1] == "\n"
|
2009-09-06 22:59:39 +08:00
|
|
|
entry_lines = entry.splitlines()
|
|
|
|
assert len(entry_lines) == 1
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry_lines[0] == ". name"
|
2009-09-06 22:59:39 +08:00
|
|
|
|
|
|
|
reslog.logfile = py.io.TextIO()
|
2018-05-23 22:48:46 +08:00
|
|
|
reslog.write_log_entry("name", "s", "Skipped")
|
2009-09-06 22:59:39 +08:00
|
|
|
entry = reslog.logfile.getvalue()
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry[-1] == "\n"
|
2009-09-06 22:59:39 +08:00
|
|
|
entry_lines = entry.splitlines()
|
|
|
|
assert len(entry_lines) == 2
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry_lines[0] == "s name"
|
|
|
|
assert entry_lines[1] == " Skipped"
|
2009-09-06 22:59:39 +08:00
|
|
|
|
|
|
|
reslog.logfile = py.io.TextIO()
|
2018-05-23 22:48:46 +08:00
|
|
|
reslog.write_log_entry("name", "s", "Skipped\n")
|
2009-09-06 22:59:39 +08:00
|
|
|
entry = reslog.logfile.getvalue()
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry[-1] == "\n"
|
2009-09-06 22:59:39 +08:00
|
|
|
entry_lines = entry.splitlines()
|
|
|
|
assert len(entry_lines) == 2
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry_lines[0] == "s name"
|
|
|
|
assert entry_lines[1] == " Skipped"
|
2009-09-06 22:59:39 +08:00
|
|
|
|
|
|
|
reslog.logfile = py.io.TextIO()
|
2018-05-23 22:48:46 +08:00
|
|
|
longrepr = " tb1\n tb 2\nE tb3\nSome Error"
|
|
|
|
reslog.write_log_entry("name", "F", longrepr)
|
2009-09-06 22:59:39 +08:00
|
|
|
entry = reslog.logfile.getvalue()
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry[-1] == "\n"
|
2009-09-06 22:59:39 +08:00
|
|
|
entry_lines = entry.splitlines()
|
|
|
|
assert len(entry_lines) == 5
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry_lines[0] == "F name"
|
|
|
|
assert entry_lines[1:] == [" " + line for line in longrepr.splitlines()]
|
2009-09-06 22:59:39 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
|
2017-02-17 02:41:51 +08:00
|
|
|
class TestWithFunctionIntegration(object):
|
2009-09-06 22:59:39 +08:00
|
|
|
# XXX (hpk) i think that the resultlog plugin should
|
2010-07-27 03:15:15 +08:00
|
|
|
# provide a Parser object so that one can remain
|
|
|
|
# ignorant regarding formatting details.
|
2009-09-06 22:59:39 +08:00
|
|
|
def getresultlog(self, testdir, arg):
|
|
|
|
resultlog = testdir.tmpdir.join("resultlog")
|
|
|
|
testdir.plugins.append("resultlog")
|
|
|
|
args = ["--resultlog=%s" % resultlog] + [arg]
|
|
|
|
testdir.runpytest(*args)
|
|
|
|
return [x for x in resultlog.readlines(cr=0) if x]
|
2010-07-27 03:15:15 +08:00
|
|
|
|
2009-09-06 22:59:39 +08:00
|
|
|
def test_collection_report(self, testdir):
|
|
|
|
ok = testdir.makepyfile(test_collection_ok="")
|
|
|
|
fail = testdir.makepyfile(test_collection_fail="XXX")
|
2010-07-27 03:15:15 +08:00
|
|
|
lines = self.getresultlog(testdir, ok)
|
2009-09-06 22:59:39 +08:00
|
|
|
assert not lines
|
|
|
|
|
|
|
|
lines = self.getresultlog(testdir, fail)
|
|
|
|
assert lines
|
|
|
|
assert lines[0].startswith("F ")
|
|
|
|
assert lines[0].endswith("test_collection_fail.py"), lines[0]
|
|
|
|
for x in lines[1:]:
|
|
|
|
assert x.startswith(" ")
|
|
|
|
assert "XXX" in "".join(lines[1:])
|
|
|
|
|
|
|
|
def test_log_test_outcomes(self, testdir):
|
2018-05-23 22:48:46 +08:00
|
|
|
mod = testdir.makepyfile(
|
|
|
|
test_mod="""
|
2010-11-18 05:12:16 +08:00
|
|
|
import pytest
|
2009-09-06 22:59:39 +08:00
|
|
|
def test_pass(): pass
|
2010-11-18 05:12:16 +08:00
|
|
|
def test_skip(): pytest.skip("hello")
|
2009-09-17 21:31:35 +08:00
|
|
|
def test_fail(): raise ValueError("FAIL")
|
|
|
|
|
2010-11-18 05:12:16 +08:00
|
|
|
@pytest.mark.xfail
|
2009-09-17 21:31:35 +08:00
|
|
|
def test_xfail(): raise ValueError("XFAIL")
|
2010-11-18 05:12:16 +08:00
|
|
|
@pytest.mark.xfail
|
2010-07-27 03:15:15 +08:00
|
|
|
def test_xpass(): pass
|
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
2009-09-06 22:59:39 +08:00
|
|
|
lines = self.getresultlog(testdir, mod)
|
|
|
|
assert len(lines) >= 3
|
|
|
|
assert lines[0].startswith(". ")
|
|
|
|
assert lines[0].endswith("test_pass")
|
|
|
|
assert lines[1].startswith("s "), lines[1]
|
2010-07-27 03:15:15 +08:00
|
|
|
assert lines[1].endswith("test_skip")
|
2009-09-06 22:59:39 +08:00
|
|
|
assert lines[2].find("hello") != -1
|
2010-07-27 03:15:15 +08:00
|
|
|
|
2009-09-06 22:59:39 +08:00
|
|
|
assert lines[3].startswith("F ")
|
|
|
|
assert lines[3].endswith("test_fail")
|
2009-09-17 21:31:35 +08:00
|
|
|
tb = "".join(lines[4:8])
|
|
|
|
assert tb.find('raise ValueError("FAIL")') != -1
|
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
assert lines[8].startswith("x ")
|
2009-09-17 21:31:35 +08:00
|
|
|
tb = "".join(lines[8:14])
|
|
|
|
assert tb.find('raise ValueError("XFAIL")') != -1
|
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
assert lines[14].startswith("X ")
|
2009-09-17 21:31:35 +08:00
|
|
|
assert len(lines) == 15
|
2009-09-06 22:59:39 +08:00
|
|
|
|
2011-12-10 16:49:21 +08:00
|
|
|
@pytest.mark.parametrize("style", ("native", "long", "short"))
|
|
|
|
def test_internal_exception(self, style):
|
2009-09-06 22:59:39 +08:00
|
|
|
# they are produced for example by a teardown failing
|
2011-12-10 16:49:21 +08:00
|
|
|
# at the end of the run or a failing hook invocation
|
2009-09-06 22:59:39 +08:00
|
|
|
try:
|
|
|
|
raise ValueError
|
|
|
|
except ValueError:
|
2015-11-27 22:43:01 +08:00
|
|
|
excinfo = _pytest._code.ExceptionInfo()
|
2010-07-27 03:15:15 +08:00
|
|
|
reslog = ResultLog(None, py.io.TextIO())
|
2011-12-10 16:49:21 +08:00
|
|
|
reslog.pytest_internalerror(excinfo.getrepr(style=style))
|
2009-09-06 22:59:39 +08:00
|
|
|
entry = reslog.logfile.getvalue()
|
|
|
|
entry_lines = entry.splitlines()
|
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry_lines[0].startswith("! ")
|
2011-12-10 16:49:21 +08:00
|
|
|
if style != "native":
|
2017-07-17 07:25:09 +08:00
|
|
|
assert os.path.basename(__file__)[:-9] in entry_lines[0] # .pyc/class
|
2018-05-23 22:48:46 +08:00
|
|
|
assert entry_lines[-1][0] == " "
|
|
|
|
assert "ValueError" in entry
|
2009-09-06 22:59:39 +08:00
|
|
|
|
2011-12-10 16:49:21 +08:00
|
|
|
|
2009-09-06 22:59:39 +08:00
|
|
|
def test_generic(testdir, LineMatcher):
|
|
|
|
testdir.plugins.append("resultlog")
|
2018-05-23 22:48:46 +08:00
|
|
|
testdir.makepyfile(
|
|
|
|
"""
|
2010-11-18 05:12:16 +08:00
|
|
|
import pytest
|
2009-09-06 22:59:39 +08:00
|
|
|
def test_pass():
|
|
|
|
pass
|
|
|
|
def test_fail():
|
|
|
|
assert 0
|
|
|
|
def test_skip():
|
2010-11-18 05:12:16 +08:00
|
|
|
pytest.skip("")
|
|
|
|
@pytest.mark.xfail
|
2009-09-17 21:31:35 +08:00
|
|
|
def test_xfail():
|
|
|
|
assert 0
|
2010-11-18 05:12:16 +08:00
|
|
|
@pytest.mark.xfail(run=False)
|
2010-05-03 04:13:16 +08:00
|
|
|
def test_xfail_norun():
|
|
|
|
assert 0
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
2009-09-06 22:59:39 +08:00
|
|
|
testdir.runpytest("--resultlog=result.log")
|
|
|
|
lines = testdir.tmpdir.join("result.log").readlines(cr=0)
|
2018-05-23 22:48:46 +08:00
|
|
|
LineMatcher(lines).fnmatch_lines(
|
|
|
|
[
|
|
|
|
". *:test_pass",
|
|
|
|
"F *:test_fail",
|
|
|
|
"s *:test_skip",
|
|
|
|
"x *:test_xfail",
|
|
|
|
"x *:test_xfail_norun",
|
|
|
|
]
|
|
|
|
)
|
2010-07-02 19:01:21 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2015-06-17 06:36:04 +08:00
|
|
|
def test_makedir_for_resultlog(testdir, LineMatcher):
|
2015-06-17 11:04:25 +08:00
|
|
|
"""--resultlog should automatically create directories for the log file"""
|
2015-06-17 06:36:04 +08:00
|
|
|
testdir.plugins.append("resultlog")
|
2018-05-23 22:48:46 +08:00
|
|
|
testdir.makepyfile(
|
|
|
|
"""
|
2015-06-17 06:36:04 +08:00
|
|
|
import pytest
|
|
|
|
def test_pass():
|
|
|
|
pass
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
2015-06-17 06:36:04 +08:00
|
|
|
testdir.runpytest("--resultlog=path/to/result.log")
|
|
|
|
lines = testdir.tmpdir.join("path/to/result.log").readlines(cr=0)
|
2018-05-23 22:48:46 +08:00
|
|
|
LineMatcher(lines).fnmatch_lines([". *:test_pass"])
|
2015-06-17 06:36:04 +08:00
|
|
|
|
|
|
|
|
2010-07-02 19:01:21 +08:00
|
|
|
def test_no_resultlog_on_slaves(testdir):
|
|
|
|
config = testdir.parseconfig("-p", "resultlog", "--resultlog=resultlog")
|
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
assert not hasattr(config, "_resultlog")
|
2010-07-02 19:01:21 +08:00
|
|
|
pytest_configure(config)
|
2018-05-23 22:48:46 +08:00
|
|
|
assert hasattr(config, "_resultlog")
|
2010-07-02 19:01:21 +08:00
|
|
|
pytest_unconfigure(config)
|
2018-05-23 22:48:46 +08:00
|
|
|
assert not hasattr(config, "_resultlog")
|
2010-07-02 19:01:21 +08:00
|
|
|
|
|
|
|
config.slaveinput = {}
|
|
|
|
pytest_configure(config)
|
2018-05-23 22:48:46 +08:00
|
|
|
assert not hasattr(config, "_resultlog")
|
2010-07-02 19:01:21 +08:00
|
|
|
pytest_unconfigure(config)
|
2018-05-23 22:48:46 +08:00
|
|
|
assert not hasattr(config, "_resultlog")
|
2010-07-02 19:01:21 +08:00
|
|
|
|
2013-11-19 21:19:29 +08:00
|
|
|
|
|
|
|
def test_failure_issue380(testdir):
|
2018-05-23 22:48:46 +08:00
|
|
|
testdir.makeconftest(
|
|
|
|
"""
|
2013-11-19 21:19:29 +08:00
|
|
|
import pytest
|
|
|
|
class MyCollector(pytest.File):
|
|
|
|
def collect(self):
|
|
|
|
raise ValueError()
|
|
|
|
def repr_failure(self, excinfo):
|
|
|
|
return "somestring"
|
|
|
|
def pytest_collect_file(path, parent):
|
|
|
|
return MyCollector(parent=parent, fspath=path)
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
testdir.makepyfile(
|
|
|
|
"""
|
2013-11-19 21:19:29 +08:00
|
|
|
def test_func():
|
|
|
|
pass
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
2013-11-19 21:19:29 +08:00
|
|
|
result = testdir.runpytest("--resultlog=log")
|
2016-06-20 21:05:50 +08:00
|
|
|
assert result.ret == 2
|