Merge pull request #2468 from nicoddemus/collection-report-2464
Fix incorrect "collected items" report when specifying tests on the command-line
This commit is contained in:
commit
4e57a39067
|
@ -763,7 +763,11 @@ class Session(FSCollector):
|
||||||
if not has_matched and len(rep.result) == 1 and x.name == "()":
|
if not has_matched and len(rep.result) == 1 and x.name == "()":
|
||||||
nextnames.insert(0, name)
|
nextnames.insert(0, name)
|
||||||
resultnodes.extend(self.matchnodes([x], nextnames))
|
resultnodes.extend(self.matchnodes([x], nextnames))
|
||||||
node.ihook.pytest_collectreport(report=rep)
|
else:
|
||||||
|
# report collection failures here to avoid failing to run some test
|
||||||
|
# specified in the command line because the module could not be
|
||||||
|
# imported (#134)
|
||||||
|
node.ihook.pytest_collectreport(report=rep)
|
||||||
return resultnodes
|
return resultnodes
|
||||||
|
|
||||||
def genitems(self, node):
|
def genitems(self, node):
|
||||||
|
|
|
@ -282,7 +282,7 @@ class TerminalReporter:
|
||||||
line = "collected "
|
line = "collected "
|
||||||
else:
|
else:
|
||||||
line = "collecting "
|
line = "collecting "
|
||||||
line += str(self._numcollected) + " items"
|
line += str(self._numcollected) + " item" + ('' if self._numcollected == 1 else 's')
|
||||||
if errors:
|
if errors:
|
||||||
line += " / %d errors" % errors
|
line += " / %d errors" % errors
|
||||||
if skipped:
|
if skipped:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix incorrect "collected items" report when specifying tests on the command-line.
|
|
@ -317,8 +317,8 @@ class TestGeneralUsage(object):
|
||||||
])
|
])
|
||||||
assert 'sessionstarttime' not in result.stderr.str()
|
assert 'sessionstarttime' not in result.stderr.str()
|
||||||
|
|
||||||
@pytest.mark.parametrize('lookfor', ['test_fun.py', 'test_fun.py::test_a'])
|
@pytest.mark.parametrize('lookfor', ['test_fun.py::test_a'])
|
||||||
def test_issue134_report_syntaxerror_when_collecting_member(self, testdir, lookfor):
|
def test_issue134_report_error_when_collecting_member(self, testdir, lookfor):
|
||||||
testdir.makepyfile(test_fun="""
|
testdir.makepyfile(test_fun="""
|
||||||
def test_a():
|
def test_a():
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -369,6 +369,11 @@ class TestSession(object):
|
||||||
assert len(colitems) == 1
|
assert len(colitems) == 1
|
||||||
assert colitems[0].fspath == p
|
assert colitems[0].fspath == p
|
||||||
|
|
||||||
|
def get_reported_items(self, hookrec):
|
||||||
|
"""Return pytest.Item instances reported by the pytest_collectreport hook"""
|
||||||
|
calls = hookrec.getcalls('pytest_collectreport')
|
||||||
|
return [x for call in calls for x in call.report.result
|
||||||
|
if isinstance(x, pytest.Item)]
|
||||||
|
|
||||||
def test_collect_protocol_single_function(self, testdir):
|
def test_collect_protocol_single_function(self, testdir):
|
||||||
p = testdir.makepyfile("def test_func(): pass")
|
p = testdir.makepyfile("def test_func(): pass")
|
||||||
|
@ -386,9 +391,10 @@ class TestSession(object):
|
||||||
("pytest_collectstart", "collector.fspath == p"),
|
("pytest_collectstart", "collector.fspath == p"),
|
||||||
("pytest_make_collect_report", "collector.fspath == p"),
|
("pytest_make_collect_report", "collector.fspath == p"),
|
||||||
("pytest_pycollect_makeitem", "name == 'test_func'"),
|
("pytest_pycollect_makeitem", "name == 'test_func'"),
|
||||||
("pytest_collectreport", "report.nodeid.startswith(p.basename)"),
|
("pytest_collectreport", "report.result[0].name == 'test_func'"),
|
||||||
("pytest_collectreport", "report.nodeid == ''")
|
|
||||||
])
|
])
|
||||||
|
# ensure we are reporting the collection of the single test item (#2464)
|
||||||
|
assert [x.name for x in self.get_reported_items(hookrec)] == ['test_func']
|
||||||
|
|
||||||
def test_collect_protocol_method(self, testdir):
|
def test_collect_protocol_method(self, testdir):
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
|
@ -407,6 +413,8 @@ class TestSession(object):
|
||||||
assert items[0].name == "test_method"
|
assert items[0].name == "test_method"
|
||||||
newid = items[0].nodeid
|
newid = items[0].nodeid
|
||||||
assert newid == normid
|
assert newid == normid
|
||||||
|
# ensure we are reporting the collection of the single test item (#2464)
|
||||||
|
assert [x.name for x in self.get_reported_items(hookrec)] == ['test_method']
|
||||||
|
|
||||||
def test_collect_custom_nodes_multi_id(self, testdir):
|
def test_collect_custom_nodes_multi_id(self, testdir):
|
||||||
p = testdir.makepyfile("def test_func(): pass")
|
p = testdir.makepyfile("def test_func(): pass")
|
||||||
|
@ -436,9 +444,8 @@ class TestSession(object):
|
||||||
"collector.__class__.__name__ == 'Module'"),
|
"collector.__class__.__name__ == 'Module'"),
|
||||||
("pytest_pycollect_makeitem", "name == 'test_func'"),
|
("pytest_pycollect_makeitem", "name == 'test_func'"),
|
||||||
("pytest_collectreport", "report.nodeid.startswith(p.basename)"),
|
("pytest_collectreport", "report.nodeid.startswith(p.basename)"),
|
||||||
#("pytest_collectreport",
|
|
||||||
# "report.fspath == %r" % str(rcol.fspath)),
|
|
||||||
])
|
])
|
||||||
|
assert len(self.get_reported_items(hookrec)) == 2
|
||||||
|
|
||||||
def test_collect_subdir_event_ordering(self, testdir):
|
def test_collect_subdir_event_ordering(self, testdir):
|
||||||
p = testdir.makepyfile("def test_func(): pass")
|
p = testdir.makepyfile("def test_func(): pass")
|
||||||
|
@ -495,11 +502,13 @@ class TestSession(object):
|
||||||
def test_method(self):
|
def test_method(self):
|
||||||
pass
|
pass
|
||||||
""")
|
""")
|
||||||
arg = p.basename + ("::TestClass::test_method")
|
arg = p.basename + "::TestClass::test_method"
|
||||||
items, hookrec = testdir.inline_genitems(arg)
|
items, hookrec = testdir.inline_genitems(arg)
|
||||||
assert len(items) == 1
|
assert len(items) == 1
|
||||||
item, = items
|
item, = items
|
||||||
assert item.nodeid.endswith("TestClass::()::test_method")
|
assert item.nodeid.endswith("TestClass::()::test_method")
|
||||||
|
# ensure we are reporting the collection of the single test item (#2464)
|
||||||
|
assert [x.name for x in self.get_reported_items(hookrec)] == ['test_method']
|
||||||
|
|
||||||
class Test_getinitialnodes(object):
|
class Test_getinitialnodes(object):
|
||||||
def test_global_file(self, testdir, tmpdir):
|
def test_global_file(self, testdir, tmpdir):
|
||||||
|
|
|
@ -513,12 +513,12 @@ def test_pytest_no_tests_collected_exit_status(testdir):
|
||||||
assert 1
|
assert 1
|
||||||
""")
|
""")
|
||||||
result = testdir.runpytest()
|
result = testdir.runpytest()
|
||||||
result.stdout.fnmatch_lines('*collected 1 items*')
|
result.stdout.fnmatch_lines('*collected 1 item*')
|
||||||
result.stdout.fnmatch_lines('*1 passed*')
|
result.stdout.fnmatch_lines('*1 passed*')
|
||||||
assert result.ret == main.EXIT_OK
|
assert result.ret == main.EXIT_OK
|
||||||
|
|
||||||
result = testdir.runpytest('-k nonmatch')
|
result = testdir.runpytest('-k nonmatch')
|
||||||
result.stdout.fnmatch_lines('*collected 1 items*')
|
result.stdout.fnmatch_lines('*collected 1 item*')
|
||||||
result.stdout.fnmatch_lines('*1 deselected*')
|
result.stdout.fnmatch_lines('*1 deselected*')
|
||||||
assert result.ret == main.EXIT_NOTESTSCOLLECTED
|
assert result.ret == main.EXIT_NOTESTSCOLLECTED
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,15 @@ class TestTerminal(object):
|
||||||
assert result.ret == 2
|
assert result.ret == 2
|
||||||
result.stdout.fnmatch_lines(['*KeyboardInterrupt*'])
|
result.stdout.fnmatch_lines(['*KeyboardInterrupt*'])
|
||||||
|
|
||||||
|
def test_collect_single_item(self, testdir):
|
||||||
|
"""Use singular 'item' when reporting a single test item"""
|
||||||
|
testdir.makepyfile("""
|
||||||
|
def test_foobar():
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines(['collected 1 item'])
|
||||||
|
|
||||||
|
|
||||||
class TestCollectonly(object):
|
class TestCollectonly(object):
|
||||||
def test_collectonly_basic(self, testdir):
|
def test_collectonly_basic(self, testdir):
|
||||||
|
|
Loading…
Reference in New Issue