Created
September 9, 2020 11:28
-
-
Save mgedmin/845566c50fefcced425a55ee87632816 to your computer and use it in GitHub Desktop.
How to get a pytest progress bar in xterm title
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Put this in your top-level conftest.py | |
class XTermProgress: | |
def __init__(self, stdout=sys.stdout): | |
self.init(stdout) | |
self.session = None | |
self.reported = set() | |
self.args = [] | |
def init(self, stdout): | |
self.stdout = stdout | |
self.enabled = os.environ.get('TERM', '').startswith('xterm') and stdout.isatty() | |
def ready(self, session): | |
self.session = session | |
def set_args(self, args): | |
self.args = list(args) | |
@property | |
def finished_tests(self): | |
return len(self.reported) | |
@property | |
def total_tests(self): | |
return self.session.testscollected | |
@property | |
def progress(self): | |
if self.total_tests == 0: | |
return '0%' | |
else: | |
return f'{100 * self.finished_tests / self.total_tests:.1f}%' | |
def logreport(self, report): | |
if self.enabled: | |
self.reported.add(report.nodeid) | |
message = f"{self.progress} - {' '.join(['pytest'] + self.args)}" | |
self.stdout.write(f"\033]0;{message}\a") | |
self.stdout.flush() | |
TERMINAL_PROGRESS = XTermProgress() | |
@pytest.mark.trylast | |
def pytest_configure(config): | |
standard_reporter = config.pluginmanager.getplugin('terminalreporter') | |
if hasattr(getattr(standard_reporter, '_tw', None), '_file'): | |
# XXX: I was unable to find a blessed way of getting the real stdout | |
# stream from pytest APIs, and I can't use standard_reporter.write() because | |
# it sprinkles extraneous newlines everywhere! | |
TERMINAL_PROGRESS.init(standard_reporter._tw._file) | |
if hasattr(config, 'invocation_params'): # pytest 5.1 required | |
TERMINAL_PROGRESS.set_args(config.invocation_params.args) | |
def pytest_collection(session): | |
TERMINAL_PROGRESS.ready(session) | |
def pytest_runtest_logreport(report): | |
TERMINAL_PROGRESS.logreport(report) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment