Capture qutebrowser/httpbin output separately.

When using print and relying on pytest to capture it as stdout, we ran into
this pytest/pytest-qt issue:

https://github.com/pytest-dev/pytest-qt/issues/113

Now we use our own capturing mechanism instead, which also means we get nicer
output.

Fixes #1122.
This commit is contained in:
Florian Bruhin 2015-12-16 20:17:29 +01:00
parent 7f83c6c5c8
commit bba6589e19
4 changed files with 38 additions and 7 deletions

View File

@ -23,3 +23,4 @@
from webserver import httpbin, httpbin_after_test
from quteprocess import quteproc_process, quteproc
from testprocess import pytest_runtest_makereport

View File

@ -174,7 +174,7 @@ class QuteProc(testprocess.Process):
# pylint: disable=no-member
if (log_line.loglevel in ['INFO', 'WARNING', 'ERROR'] or
pytest.config.getoption('--verbose')):
print(line)
self._log(line)
start_okay_message_load = (
"load status for <qutebrowser.browser.webview.WebView tab_id=0 "
@ -306,7 +306,7 @@ class QuteProc(testprocess.Process):
with open(session, encoding='utf-8') as f:
data = f.read()
print(data)
self._log(data)
return yaml.load(data)
def get_content(self, plain=True):
@ -341,8 +341,9 @@ def quteproc_process(qapp, httpbin, request):
@pytest.yield_fixture
def quteproc(quteproc_process, httpbin):
def quteproc(quteproc_process, httpbin, request):
"""Per-test qutebrowser fixture which uses the per-file process."""
request.node._quteproc_log = quteproc_process.captured_log
quteproc_process.before_test()
yield quteproc_process
quteproc_process.after_test()

View File

@ -23,6 +23,7 @@ import re
import os
import time
import pytest
import pytestqt.plugin
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QProcess, QObject, QElapsedTimer
from PyQt5.QtTest import QSignalSpy
@ -71,6 +72,28 @@ class Line:
return '{}({!r})'.format(self.__class__.__name__, self.data)
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
"""Add qutebrowser/httpbin sections to captured output if a test failed."""
outcome = yield
if call.when != 'call':
return
report = outcome.get_result()
if report.passed:
return
quteproc_log = getattr(item, '_quteproc_log', None)
httpbin_log = getattr(item, '_httpbin_log', None)
if quteproc_log is not None:
report.longrepr.addsection("qutebrowser output",
'\n'.join(quteproc_log))
if httpbin_log is not None:
report.longrepr.addsection("httpbin output",
'\n'.join(httpbin_log))
class Process(QObject):
"""Abstraction over a running test subprocess process.
@ -93,11 +116,16 @@ class Process(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.captured_log = []
self._invalid = []
self._data = []
self.proc = QProcess()
self.proc.setReadChannel(QProcess.StandardError)
def _log(self, line):
"""Add the given line to the captured log output."""
self.captured_log.append(line)
def _parse_line(self, line):
"""Parse the given line from the log.
@ -146,12 +174,12 @@ class Process(QObject):
parsed = self._parse_line(line)
except InvalidLine:
self._invalid.append(line)
print("INVALID: {}".format(line))
self._log("INVALID: {}".format(line))
continue
if parsed is None:
if self._invalid:
print("IGNORED: {}".format(line))
self._log("IGNORED: {}".format(line))
else:
self._data.append(parsed)
self.new_data.emit(parsed)

View File

@ -129,7 +129,7 @@ class HTTPBin(testprocess.Process):
return [r for r in requests if r.path != '/favicon.ico']
def _parse_line(self, line):
print(line)
self._log(line)
if line == (' * Running on http://127.0.0.1:{}/ (Press CTRL+C to '
'quit)'.format(self.port)):
self.ready.emit()
@ -164,7 +164,8 @@ def httpbin(qapp):
@pytest.yield_fixture(autouse=True)
def httpbin_after_test(httpbin):
def httpbin_after_test(httpbin, request):
"""Fixture to clean httpbin request list after each test."""
request.node._httpbin_log = httpbin.captured_log
yield
httpbin.after_test()