diff --git a/_pytest/terminal.py b/_pytest/terminal.py index 7dd10924a..bb114391d 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -180,8 +180,22 @@ class TerminalReporter: self._tw.line(line, **markup) def rewrite(self, line, **markup): + """ + Rewinds the terminal cursor to the beginning and writes the given line. + + :kwarg erase: if True, will also add spaces until the full terminal width to ensure + previous lines are properly erased. + + The rest of the keyword arguments are markup instructions. + """ + erase = markup.pop('erase', False) + if erase: + fill_count = self._tw.fullwidth - len(line) + fill = ' ' * fill_count + else: + fill = '' line = str(line) - self._tw.write("\r" + line, **markup) + self._tw.write("\r" + line + fill, **markup) def write_sep(self, sep, title=None, **markup): self.ensure_newline() @@ -292,12 +306,9 @@ class TerminalReporter: if skipped: line += " / %d skipped" % skipped if self.isatty: + self.rewrite(line, bold=True, erase=True) if final: - line += " \n" - # Rewrite with empty line so we will not see the artifact of - # previous write - self.rewrite('') - self.rewrite(line, bold=True) + self.write('\n') else: self.write_line(line) diff --git a/changelog/2579.bugfix b/changelog/2579.bugfix new file mode 100644 index 000000000..bb046b3c8 --- /dev/null +++ b/changelog/2579.bugfix @@ -0,0 +1 @@ +Fixed small terminal glitch when collecting a single test item. diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 6b20c3a48..9bd607783 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -214,6 +214,16 @@ class TestTerminal(object): result = testdir.runpytest() result.stdout.fnmatch_lines(['collected 1 item']) + def test_rewrite(self, testdir, monkeypatch): + config = testdir.parseconfig() + f = py.io.TextIO() + monkeypatch.setattr(f, 'isatty', lambda *args: True) + tr = TerminalReporter(config, f) + tr.writer.fullwidth = 10 + tr.write('hello') + tr.rewrite('hey', erase=True) + assert f.getvalue() == 'hello' + '\r' + 'hey' + (7 * ' ') + class TestCollectonly(object): def test_collectonly_basic(self, testdir):