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,6 +763,10 @@ 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)) | ||||||
|  |             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) |                 node.ihook.pytest_collectreport(report=rep) | ||||||
|         return resultnodes |         return resultnodes | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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