parent
b0032ba2b3
commit
5939b336cd
|
@ -152,9 +152,9 @@ class TerminalReporter:
|
||||||
self.reportchars = getreportopt(config)
|
self.reportchars = getreportopt(config)
|
||||||
self.hasmarkup = self._tw.hasmarkup
|
self.hasmarkup = self._tw.hasmarkup
|
||||||
self.isatty = file.isatty()
|
self.isatty = file.isatty()
|
||||||
self._progress_items_reported = 0
|
self._progress_nodeids_reported = set()
|
||||||
self._show_progress_info = (self.config.getoption('capture') != 'no' and
|
self._show_progress_info = (self.config.getoption('capture') != 'no' and not self.config.getoption('setupshow')
|
||||||
self.config.getini('console_output_style') == 'progress')
|
and self.config.getini('console_output_style') == 'progress')
|
||||||
|
|
||||||
def hasopt(self, char):
|
def hasopt(self, char):
|
||||||
char = {'xfailed': 'x', 'skipped': 's'}.get(char, char)
|
char = {'xfailed': 'x', 'skipped': 's'}.get(char, char)
|
||||||
|
@ -179,7 +179,6 @@ class TerminalReporter:
|
||||||
if extra:
|
if extra:
|
||||||
self._tw.write(extra, **kwargs)
|
self._tw.write(extra, **kwargs)
|
||||||
self.currentfspath = -2
|
self.currentfspath = -2
|
||||||
self._write_progress_information_filling_space()
|
|
||||||
|
|
||||||
def ensure_newline(self):
|
def ensure_newline(self):
|
||||||
if self.currentfspath:
|
if self.currentfspath:
|
||||||
|
@ -269,14 +268,13 @@ class TerminalReporter:
|
||||||
# probably passed setup/teardown
|
# probably passed setup/teardown
|
||||||
return
|
return
|
||||||
running_xdist = hasattr(rep, 'node')
|
running_xdist = hasattr(rep, 'node')
|
||||||
self._progress_items_reported += 1
|
|
||||||
if self.verbosity <= 0:
|
if self.verbosity <= 0:
|
||||||
if not running_xdist and self.showfspath:
|
if not running_xdist and self.showfspath:
|
||||||
self.write_fspath_result(rep.nodeid, letter)
|
self.write_fspath_result(rep.nodeid, letter)
|
||||||
else:
|
else:
|
||||||
self._tw.write(letter)
|
self._tw.write(letter)
|
||||||
self._write_progress_if_past_edge()
|
|
||||||
else:
|
else:
|
||||||
|
self._progress_nodeids_reported.add(rep.nodeid)
|
||||||
if markup is None:
|
if markup is None:
|
||||||
if rep.passed:
|
if rep.passed:
|
||||||
markup = {'green': True}
|
markup = {'green': True}
|
||||||
|
@ -289,6 +287,8 @@ class TerminalReporter:
|
||||||
line = self._locationline(rep.nodeid, *rep.location)
|
line = self._locationline(rep.nodeid, *rep.location)
|
||||||
if not running_xdist:
|
if not running_xdist:
|
||||||
self.write_ensure_prefix(line, word, **markup)
|
self.write_ensure_prefix(line, word, **markup)
|
||||||
|
if self._show_progress_info:
|
||||||
|
self._write_progress_information_filling_space()
|
||||||
else:
|
else:
|
||||||
self.ensure_newline()
|
self.ensure_newline()
|
||||||
self._tw.write("[%s]" % rep.node.gateway.id)
|
self._tw.write("[%s]" % rep.node.gateway.id)
|
||||||
|
@ -300,31 +300,28 @@ class TerminalReporter:
|
||||||
self._tw.write(" " + line)
|
self._tw.write(" " + line)
|
||||||
self.currentfspath = -2
|
self.currentfspath = -2
|
||||||
|
|
||||||
def _write_progress_if_past_edge(self):
|
def pytest_runtest_logfinish(self, nodeid):
|
||||||
if not self._show_progress_info:
|
if self.verbosity <= 0 and self._show_progress_info:
|
||||||
return
|
self._progress_nodeids_reported.add(nodeid)
|
||||||
last_item = self._progress_items_reported == self._session.testscollected
|
last_item = len(self._progress_nodeids_reported) == self._session.testscollected
|
||||||
if last_item:
|
if last_item:
|
||||||
self._write_progress_information_filling_space()
|
self._write_progress_information_filling_space()
|
||||||
return
|
else:
|
||||||
|
past_edge = self._tw.chars_on_current_line + self._PROGRESS_LENGTH + 1 >= self._screen_width
|
||||||
past_edge = self._tw.chars_on_current_line + self._PROGRESS_LENGTH + 1 >= self._screen_width
|
if past_edge:
|
||||||
if past_edge:
|
msg = self._get_progress_information_message()
|
||||||
msg = self._get_progress_information_message()
|
self._tw.write(msg + '\n', cyan=True)
|
||||||
self._tw.write(msg + '\n', cyan=True)
|
|
||||||
|
|
||||||
_PROGRESS_LENGTH = len(' [100%]')
|
_PROGRESS_LENGTH = len(' [100%]')
|
||||||
|
|
||||||
def _get_progress_information_message(self):
|
def _get_progress_information_message(self):
|
||||||
collected = self._session.testscollected
|
collected = self._session.testscollected
|
||||||
if collected:
|
if collected:
|
||||||
progress = self._progress_items_reported * 100 // collected
|
progress = len(self._progress_nodeids_reported) * 100 // collected
|
||||||
return ' [{:3d}%]'.format(progress)
|
return ' [{:3d}%]'.format(progress)
|
||||||
return ' [100%]'
|
return ' [100%]'
|
||||||
|
|
||||||
def _write_progress_information_filling_space(self):
|
def _write_progress_information_filling_space(self):
|
||||||
if not self._show_progress_info:
|
|
||||||
return
|
|
||||||
msg = self._get_progress_information_message()
|
msg = self._get_progress_information_message()
|
||||||
fill = ' ' * (self._tw.fullwidth - self._tw.chars_on_current_line - len(msg) - 1)
|
fill = ' ' * (self._tw.fullwidth - self._tw.chars_on_current_line - len(msg) - 1)
|
||||||
self.write(fill + msg, cyan=True)
|
self.write(fill + msg, cyan=True)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix progress percentage reported when tests fail during teardown.
|
|
@ -969,7 +969,7 @@ def test_no_trailing_whitespace_after_inifile_word(testdir):
|
||||||
class TestProgress:
|
class TestProgress:
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def many_tests_file(self, testdir):
|
def many_tests_files(self, testdir):
|
||||||
testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
test_bar="""
|
test_bar="""
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -1006,7 +1006,7 @@ class TestProgress:
|
||||||
'=* 2 passed in *=',
|
'=* 2 passed in *=',
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_normal(self, many_tests_file, testdir):
|
def test_normal(self, many_tests_files, testdir):
|
||||||
output = testdir.runpytest()
|
output = testdir.runpytest()
|
||||||
output.stdout.re_match_lines([
|
output.stdout.re_match_lines([
|
||||||
r'test_bar.py \.{10} \s+ \[ 50%\]',
|
r'test_bar.py \.{10} \s+ \[ 50%\]',
|
||||||
|
@ -1014,7 +1014,7 @@ class TestProgress:
|
||||||
r'test_foobar.py \.{5} \s+ \[100%\]',
|
r'test_foobar.py \.{5} \s+ \[100%\]',
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_verbose(self, many_tests_file, testdir):
|
def test_verbose(self, many_tests_files, testdir):
|
||||||
output = testdir.runpytest('-v')
|
output = testdir.runpytest('-v')
|
||||||
output.stdout.re_match_lines([
|
output.stdout.re_match_lines([
|
||||||
r'test_bar.py::test_bar\[0\] PASSED \s+ \[ 5%\]',
|
r'test_bar.py::test_bar\[0\] PASSED \s+ \[ 5%\]',
|
||||||
|
@ -1022,14 +1022,14 @@ class TestProgress:
|
||||||
r'test_foobar.py::test_foobar\[4\] PASSED \s+ \[100%\]',
|
r'test_foobar.py::test_foobar\[4\] PASSED \s+ \[100%\]',
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_xdist_normal(self, many_tests_file, testdir):
|
def test_xdist_normal(self, many_tests_files, testdir):
|
||||||
pytest.importorskip('xdist')
|
pytest.importorskip('xdist')
|
||||||
output = testdir.runpytest('-n2')
|
output = testdir.runpytest('-n2')
|
||||||
output.stdout.re_match_lines([
|
output.stdout.re_match_lines([
|
||||||
r'\.{20} \s+ \[100%\]',
|
r'\.{20} \s+ \[100%\]',
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_xdist_verbose(self, many_tests_file, testdir):
|
def test_xdist_verbose(self, many_tests_files, testdir):
|
||||||
pytest.importorskip('xdist')
|
pytest.importorskip('xdist')
|
||||||
output = testdir.runpytest('-n2', '-v')
|
output = testdir.runpytest('-n2', '-v')
|
||||||
output.stdout.re_match_lines_random([
|
output.stdout.re_match_lines_random([
|
||||||
|
@ -1038,10 +1038,85 @@ class TestProgress:
|
||||||
r'\[gw\d\] \[\s*\d+%\] PASSED test_foobar.py::test_foobar\[1\]',
|
r'\[gw\d\] \[\s*\d+%\] PASSED test_foobar.py::test_foobar\[1\]',
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_capture_no(self, many_tests_file, testdir):
|
def test_capture_no(self, many_tests_files, testdir):
|
||||||
output = testdir.runpytest('-s')
|
output = testdir.runpytest('-s')
|
||||||
output.stdout.re_match_lines([
|
output.stdout.re_match_lines([
|
||||||
r'test_bar.py \.{10}',
|
r'test_bar.py \.{10}',
|
||||||
r'test_foo.py \.{5}',
|
r'test_foo.py \.{5}',
|
||||||
r'test_foobar.py \.{5}',
|
r'test_foobar.py \.{5}',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
class TestProgressWithTeardown:
|
||||||
|
"""Ensure we show the correct percentages for tests that fail during teardown (#3088)"""
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def contest_with_teardown_fixture(self, testdir):
|
||||||
|
testdir.makeconftest('''
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fail_teardown():
|
||||||
|
yield
|
||||||
|
assert False
|
||||||
|
''')
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def many_files(self, testdir, contest_with_teardown_fixture):
|
||||||
|
testdir.makepyfile(
|
||||||
|
test_bar='''
|
||||||
|
import pytest
|
||||||
|
@pytest.mark.parametrize('i', range(5))
|
||||||
|
def test_bar(fail_teardown, i):
|
||||||
|
pass
|
||||||
|
''',
|
||||||
|
test_foo='''
|
||||||
|
import pytest
|
||||||
|
@pytest.mark.parametrize('i', range(15))
|
||||||
|
def test_foo(fail_teardown, i):
|
||||||
|
pass
|
||||||
|
''',
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_teardown_simple(self, testdir, contest_with_teardown_fixture):
|
||||||
|
testdir.makepyfile('''
|
||||||
|
def test_foo(fail_teardown):
|
||||||
|
pass
|
||||||
|
''')
|
||||||
|
output = testdir.runpytest()
|
||||||
|
output.stdout.re_match_lines([
|
||||||
|
r'test_teardown_simple.py \.E\s+\[100%\]',
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_teardown_with_test_also_failing(self, testdir, contest_with_teardown_fixture):
|
||||||
|
testdir.makepyfile('''
|
||||||
|
def test_foo(fail_teardown):
|
||||||
|
assert False
|
||||||
|
''')
|
||||||
|
output = testdir.runpytest()
|
||||||
|
output.stdout.re_match_lines([
|
||||||
|
r'test_teardown_with_test_also_failing.py FE\s+\[100%\]',
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_teardown_many(self, testdir, many_files):
|
||||||
|
output = testdir.runpytest()
|
||||||
|
output.stdout.re_match_lines([
|
||||||
|
r'test_bar.py (\.E){5}\s+\[ 25%\]',
|
||||||
|
r'test_foo.py (\.E){15}\s+\[100%\]',
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_teardown_many_verbose(self, testdir, many_files):
|
||||||
|
output = testdir.runpytest('-v')
|
||||||
|
output.stdout.re_match_lines([
|
||||||
|
r'test_bar.py::test_bar\[0\] PASSED\s+\[ 5%\]',
|
||||||
|
r'test_bar.py::test_bar\[0\] ERROR\s+\[ 5%\]',
|
||||||
|
r'test_bar.py::test_bar\[4\] PASSED\s+\[ 25%\]',
|
||||||
|
r'test_bar.py::test_bar\[4\] ERROR\s+\[ 25%\]',
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_xdist_normal(self, many_files, testdir):
|
||||||
|
pytest.importorskip('xdist')
|
||||||
|
output = testdir.runpytest('-n2')
|
||||||
|
output.stdout.re_match_lines([
|
||||||
|
r'[\.E]{40} \s+ \[100%\]',
|
||||||
|
])
|
||||||
|
|
Loading…
Reference in New Issue