[py-svn] r60981 - in py/branch/pytestplugin/py/test: . plugin plugin/testing testing
hpk at codespeak.net
hpk at codespeak.net
Wed Jan 14 23:45:32 CET 2009
Author: hpk
Date: Wed Jan 14 23:45:31 2009
New Revision: 60981
Added:
py/branch/pytestplugin/py/test/plugin/
py/branch/pytestplugin/py/test/plugin/pytest_resultlog.py (contents, props changed)
- copied, changed from r60979, py/branch/pytestplugin/py/test/resultlog.py
py/branch/pytestplugin/py/test/plugin/testing/
py/branch/pytestplugin/py/test/plugin/testing/__init__.py (contents, props changed)
py/branch/pytestplugin/py/test/plugin/testing/test_resultlog.py (contents, props changed)
- copied, changed from r60979, py/branch/pytestplugin/py/test/testing/test_resultlog.py
Removed:
py/branch/pytestplugin/py/test/resultlog.py
py/branch/pytestplugin/py/test/testing/test_resultlog.py
Modified:
py/branch/pytestplugin/py/test/defaultconftest.py
py/branch/pytestplugin/py/test/session.py
py/branch/pytestplugin/py/test/testing/test_config.py
Log:
play a bit with API/plugin protocol by moving the resultlog option to a plugin
Modified: py/branch/pytestplugin/py/test/defaultconftest.py
==============================================================================
--- py/branch/pytestplugin/py/test/defaultconftest.py (original)
+++ py/branch/pytestplugin/py/test/defaultconftest.py Wed Jan 14 23:45:31 2009
@@ -113,7 +113,4 @@
Option('', '--session',
action="store", dest="session", default=None,
help="lookup given sessioname in conftest.py files and use it."),
- Option('--resultlog', action="store",
- default=None, dest="resultlog",
- help="path for machine-readable result log")
)
Copied: py/branch/pytestplugin/py/test/plugin/pytest_resultlog.py (from r60979, py/branch/pytestplugin/py/test/resultlog.py)
==============================================================================
--- py/branch/pytestplugin/py/test/resultlog.py (original)
+++ py/branch/pytestplugin/py/test/plugin/pytest_resultlog.py Wed Jan 14 23:45:31 2009
@@ -1,6 +1,28 @@
import py
from py.__.test import event
+def register_plugin(config):
+ config.register_plugin(ResultLogPlugin())
+
+class ResultLogPlugin:
+ def pytest_addoptions(self, config):
+ config.addoptions("resultlog options",
+ config.Option('--resultlog', action="store",
+ default=None, dest="resultlog",
+ help="path for machine-readable result log")
+ )
+
+ def pytest_session_init(self, session):
+ resultlog = session.config.option.resultlog
+ if resultlog:
+ logfile = open(resultlog, 'w', 1) # line buffered
+ self.resultlog = ResultLog(logfile)
+ session.bus.subscribe(self.resultlog.log_event_to_file)
+
+ def pytest_session_finish(self, session):
+ if hasattr(self, 'resultlog'):
+ session.bus.unsubscribe(self.resultlog.log_event_to_file)
+
def generic_path(item):
chain = item.listchain()
gpath = [chain[0].name]
@@ -26,8 +48,7 @@
class ResultLog(object):
- def __init__(self, bus, logfile):
- bus.subscribe(self.log_event_to_file)
+ def __init__(self, logfile):
self.logfile = logfile # preferably line buffered
def write_log_entry(self, shortrepr, name, longrepr):
@@ -49,6 +70,3 @@
elif isinstance(ev, event.InternalException):
path = ev.repr.reprcrash.path # fishing :(
self.write_log_entry('!', path, str(ev.repr))
-
-
-
Added: py/branch/pytestplugin/py/test/plugin/testing/__init__.py
==============================================================================
--- (empty file)
+++ py/branch/pytestplugin/py/test/plugin/testing/__init__.py Wed Jan 14 23:45:31 2009
@@ -0,0 +1 @@
+#
Copied: py/branch/pytestplugin/py/test/plugin/testing/test_resultlog.py (from r60979, py/branch/pytestplugin/py/test/testing/test_resultlog.py)
==============================================================================
--- py/branch/pytestplugin/py/test/testing/test_resultlog.py (original)
+++ py/branch/pytestplugin/py/test/plugin/testing/test_resultlog.py Wed Jan 14 23:45:31 2009
@@ -2,14 +2,18 @@
import py
-from py.__.test import resultlog
+import pytest_resultlog as resultlog
+
+from py.__.test import event
+from py.__.test.session import Session
+from py.__.test.testing import suptest
+from py.__.test.config import Config
from py.__.test.collect import Node, Item, FSCollector
from py.__.test.event import EventBus
from py.__.test.event import ItemTestReport, CollectionReport
from py.__.test.event import InternalException
from py.__.test.runner import OutcomeRepr
-
class Fake(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)
@@ -48,19 +52,24 @@
return node
return Item(names[-1], parent=node)
+def test_registration():
+ # this is a half-functional test, maybe should evolve to
+ # become a generic test that evolves to automatically test
+ # plugin registration
+ p = py.test.ensuretemp("registration").ensure("logfile")
+ myplugin = resultlog.ResultLogPlugin()
+ config = Config()
+ myplugin.pytest_addoptions(config)
+ config.parse(['--resultlog=%s' % p])
+ session = Session(config)
+ myplugin.pytest_session_init(session)
+ assert myplugin.resultlog.log_event_to_file in session.bus._subscribers
+ myplugin.pytest_session_finish(session)
+ assert myplugin.resultlog.log_event_to_file not in session.bus._subscribers
+
class TestResultLog(object):
-
- def test_create(self):
- bus = EventBus()
- logfile = object()
-
- reslog = resultlog.ResultLog(bus, logfile)
- assert len(bus._subscribers) == 1
- assert reslog.logfile is logfile
-
def test_write_log_entry(self):
- reslog = resultlog.ResultLog(EventBus(), None)
-
+ reslog = resultlog.ResultLog(None)
reslog.logfile = StringIO.StringIO()
reslog.write_log_entry('.', 'name', '')
entry = reslog.logfile.getvalue()
@@ -98,7 +107,7 @@
assert entry_lines[1:] == [' '+line for line in longrepr.splitlines()]
def test_log_outcome(self):
- reslog = resultlog.ResultLog(EventBus(), StringIO.StringIO())
+ reslog = resultlog.ResultLog(StringIO.StringIO())
colitem = make_item('some', 'path', 'a', 'b')
@@ -121,7 +130,8 @@
def test_item_test_passed(self):
bus = EventBus()
- reslog = resultlog.ResultLog(bus, StringIO.StringIO())
+ reslog = resultlog.ResultLog(StringIO.StringIO())
+ bus.subscribe(reslog.log_event_to_file)
colitem = make_item('proj/test', 'proj/test/mod', 'a', 'b')
@@ -138,7 +148,8 @@
def test_collection_report(self):
bus = EventBus()
- reslog = resultlog.ResultLog(bus, None)
+ reslog = resultlog.ResultLog(None)
+ bus.subscribe(reslog.log_event_to_file)
reslog.logfile = StringIO.StringIO()
colitem = make_item('proj/test', 'proj/test/mod', 'A', None)
@@ -164,7 +175,8 @@
# they are produced for example by a teardown failing
# at the end of the run
bus = EventBus()
- reslog = resultlog.ResultLog(bus, StringIO.StringIO())
+ reslog = resultlog.ResultLog(StringIO.StringIO())
+ bus.subscribe(reslog.log_event_to_file)
try:
raise ValueError
@@ -182,3 +194,25 @@
assert os.path.basename(__file__)[:-1] in entry_lines[0] #.py/.pyc
assert entry_lines[-1][0] == ' '
assert 'ValueError' in entry
+
+class TestSessionResultlog(suptest.FileCreation):
+ def test_session_resultlog(self):
+ py.test.skip("requires plugin registration mechanism")
+ from py.__.test.collect import Item
+ from py.__.test.runner import OutcomeRepr
+
+ resultlog = self.tmpdir.join("test_session_resultlog")
+ config = py.test.config._reparse([self.tmpdir,
+ '--resultlog=%s' % resultlog])
+
+ session = config.initsession()
+
+ item = Item("a", config=config)
+ outcome = OutcomeRepr('execute', '.', '')
+ rep_ev = event.ItemTestReport(item, passed=outcome)
+
+ session.bus.notify(rep_ev)
+
+ s = resultlog.read()
+ assert s.find(". a") != -1
+
Deleted: /py/branch/pytestplugin/py/test/resultlog.py
==============================================================================
--- /py/branch/pytestplugin/py/test/resultlog.py Wed Jan 14 23:45:31 2009
+++ (empty file)
@@ -1,54 +0,0 @@
-import py
-from py.__.test import event
-
-def generic_path(item):
- chain = item.listchain()
- gpath = [chain[0].name]
- fspath = chain[0].fspath
- fspart = False
- for node in chain[1:]:
- newfspath = node.fspath
- if newfspath == fspath:
- if fspart:
- gpath.append(':')
- fspart = False
- else:
- gpath.append('.')
- else:
- gpath.append('/')
- fspart = True
- name = node.name
- if name[0] in '([':
- gpath.pop()
- gpath.append(name)
- fspath = newfspath
- return ''.join(gpath)
-
-class ResultLog(object):
-
- def __init__(self, bus, logfile):
- bus.subscribe(self.log_event_to_file)
- self.logfile = logfile # preferably line buffered
-
- def write_log_entry(self, shortrepr, name, longrepr):
- print >>self.logfile, "%s %s" % (shortrepr, name)
- for line in longrepr.splitlines():
- print >>self.logfile, " %s" % line
-
- def log_outcome(self, ev):
- outcome = ev.outcome
- gpath = generic_path(ev.colitem)
- self.write_log_entry(outcome.shortrepr, gpath, str(outcome.longrepr))
-
- def log_event_to_file(self, ev):
- if isinstance(ev, event.ItemTestReport):
- self.log_outcome(ev)
- elif isinstance(ev, event.CollectionReport):
- if not ev.passed:
- self.log_outcome(ev)
- elif isinstance(ev, event.InternalException):
- path = ev.repr.reprcrash.path # fishing :(
- self.write_log_entry('!', path, str(ev.repr))
-
-
-
Modified: py/branch/pytestplugin/py/test/session.py
==============================================================================
--- py/branch/pytestplugin/py/test/session.py (original)
+++ py/branch/pytestplugin/py/test/session.py Wed Jan 14 23:45:31 2009
@@ -9,7 +9,6 @@
from py.__.test import event, outcome
from py.__.test.event import EventBus
import py.__.test.custompdb
-from py.__.test.resultlog import ResultLog
# used for genitems()
from py.__.test.outcome import Exit
@@ -35,10 +34,6 @@
print >>f, ev
f.flush()
self.bus.subscribe(eventwrite)
- resultlog = self.config.option.resultlog
- if resultlog:
- f = open(resultlog, 'w', 1) # line buffered
- self.resultlog = ResultLog(self.bus, f)
def fixoptions(self):
""" check, fix and determine conflicting options. """
Modified: py/branch/pytestplugin/py/test/testing/test_config.py
==============================================================================
--- py/branch/pytestplugin/py/test/testing/test_config.py (original)
+++ py/branch/pytestplugin/py/test/testing/test_config.py Wed Jan 14 23:45:31 2009
@@ -181,25 +181,6 @@
s = eventlog.read()
assert s.find("TestrunStart") != -1
- def test_session_resultlog(self):
- from py.__.test.collect import Item
- from py.__.test.runner import OutcomeRepr
-
- resultlog = self.tmpdir.join("test_session_resultlog")
- config = py.test.config._reparse([self.tmpdir,
- '--resultlog=%s' % resultlog])
-
- session = config.initsession()
-
- item = Item("a", config=config)
- outcome = OutcomeRepr('execute', '.', '')
- rep_ev = event.ItemTestReport(item, passed=outcome)
-
- session.bus.notify(rep_ev)
-
- s = resultlog.read()
- assert s.find(". a") != -1
-
def test_tracedir_tracer(self):
tracedir = self.tmpdir.join("tracedir")
config = py.test.config._reparse([self.tmpdir,
Deleted: /py/branch/pytestplugin/py/test/testing/test_resultlog.py
==============================================================================
--- /py/branch/pytestplugin/py/test/testing/test_resultlog.py Wed Jan 14 23:45:31 2009
+++ (empty file)
@@ -1,184 +0,0 @@
-import os, StringIO
-
-import py
-
-from py.__.test import resultlog
-from py.__.test.collect import Node, Item, FSCollector
-from py.__.test.event import EventBus
-from py.__.test.event import ItemTestReport, CollectionReport
-from py.__.test.event import InternalException
-from py.__.test.runner import OutcomeRepr
-
-
-class Fake(object):
- def __init__(self, **kwds):
- self.__dict__.update(kwds)
-
-
-def test_generic_path():
- p1 = Node('a', config='dummy')
- assert p1.fspath is None
- p2 = Node('B', parent=p1)
- p3 = Node('()', parent = p2)
- item = Item('c', parent = p3)
-
- res = resultlog.generic_path(item)
- assert res == 'a.B().c'
-
- p0 = FSCollector('proj/test', config='dummy')
- p1 = FSCollector('proj/test/a', parent=p0)
- p2 = Node('B', parent=p1)
- p3 = Node('()', parent = p2)
- p4 = Node('c', parent=p3)
- item = Item('[1]', parent = p4)
-
- res = resultlog.generic_path(item)
- assert res == 'test/a:B().c[1]'
-
-
-def make_item(*names):
- node = None
- config = "dummy"
- for name in names[:-1]:
- if '/' in name:
- node = FSCollector(name, parent=node, config=config)
- else:
- node = Node(name, parent=node, config=config)
- if names[-1] is None:
- return node
- return Item(names[-1], parent=node)
-
-class TestResultLog(object):
-
- def test_create(self):
- bus = EventBus()
- logfile = object()
-
- reslog = resultlog.ResultLog(bus, logfile)
- assert len(bus._subscribers) == 1
- assert reslog.logfile is logfile
-
- def test_write_log_entry(self):
- reslog = resultlog.ResultLog(EventBus(), None)
-
- reslog.logfile = StringIO.StringIO()
- reslog.write_log_entry('.', 'name', '')
- entry = reslog.logfile.getvalue()
- assert entry[-1] == '\n'
- entry_lines = entry.splitlines()
- assert len(entry_lines) == 1
- assert entry_lines[0] == '. name'
-
- reslog.logfile = StringIO.StringIO()
- reslog.write_log_entry('s', 'name', 'Skipped')
- entry = reslog.logfile.getvalue()
- assert entry[-1] == '\n'
- entry_lines = entry.splitlines()
- assert len(entry_lines) == 2
- assert entry_lines[0] == 's name'
- assert entry_lines[1] == ' Skipped'
-
- reslog.logfile = StringIO.StringIO()
- reslog.write_log_entry('s', 'name', 'Skipped\n')
- entry = reslog.logfile.getvalue()
- assert entry[-1] == '\n'
- entry_lines = entry.splitlines()
- assert len(entry_lines) == 2
- assert entry_lines[0] == 's name'
- assert entry_lines[1] == ' Skipped'
-
- reslog.logfile = StringIO.StringIO()
- longrepr = ' tb1\n tb 2\nE tb3\nSome Error'
- reslog.write_log_entry('F', 'name', longrepr)
- entry = reslog.logfile.getvalue()
- assert entry[-1] == '\n'
- entry_lines = entry.splitlines()
- assert len(entry_lines) == 5
- assert entry_lines[0] == 'F name'
- assert entry_lines[1:] == [' '+line for line in longrepr.splitlines()]
-
- def test_log_outcome(self):
- reslog = resultlog.ResultLog(EventBus(), StringIO.StringIO())
-
- colitem = make_item('some', 'path', 'a', 'b')
-
- try:
- raise ValueError
- except ValueError:
- the_repr = py.code.ExceptionInfo().getrepr()
-
- outcome=OutcomeRepr('execute', 'F', the_repr)
- ev = Fake(colitem=colitem, outcome=outcome)
-
- reslog.log_outcome(ev)
-
- entry = reslog.logfile.getvalue()
- entry_lines = entry.splitlines()
-
- assert entry_lines[0] == 'F some.path.a.b'
- assert entry_lines[-1][0] == ' '
- assert 'ValueError' in entry
-
- def test_item_test_passed(self):
- bus = EventBus()
- reslog = resultlog.ResultLog(bus, StringIO.StringIO())
-
- colitem = make_item('proj/test', 'proj/test/mod', 'a', 'b')
-
- outcome=OutcomeRepr('execute', '.', '')
- rep_ev = ItemTestReport(colitem, passed=outcome)
-
- bus.notify(rep_ev)
-
- lines = reslog.logfile.getvalue().splitlines()
- assert len(lines) == 1
- line = lines[0]
- assert line.startswith(". ")
- assert line[2:] == 'test/mod:a.b'
-
- def test_collection_report(self):
- bus = EventBus()
- reslog = resultlog.ResultLog(bus, None)
-
- reslog.logfile = StringIO.StringIO()
- colitem = make_item('proj/test', 'proj/test/mod', 'A', None)
- outcome=OutcomeRepr('execute', '', '')
- rep_ev = CollectionReport(colitem, object(), passed=outcome)
-
- bus.notify(rep_ev)
-
- entry = reslog.logfile.getvalue()
- assert not entry
-
- reslog.logfile = StringIO.StringIO()
- outcome=OutcomeRepr('execute', 'F', 'Some Error')
- rep_ev = CollectionReport(colitem, object(), failed=outcome)
-
- bus.notify(rep_ev)
-
- lines = reslog.logfile.getvalue().splitlines()
- assert len(lines) == 2
- assert lines[0] == 'F test/mod:A'
-
- def test_internal_exception(self):
- # they are produced for example by a teardown failing
- # at the end of the run
- bus = EventBus()
- reslog = resultlog.ResultLog(bus, StringIO.StringIO())
-
- try:
- raise ValueError
- except ValueError:
- excinfo = py.code.ExceptionInfo()
-
- internal = InternalException(excinfo)
-
- bus.notify(internal)
-
- entry = reslog.logfile.getvalue()
- entry_lines = entry.splitlines()
-
- assert entry_lines[0].startswith('! ')
- assert os.path.basename(__file__)[:-1] in entry_lines[0] #.py/.pyc
- assert entry_lines[-1][0] == ' '
- assert 'ValueError' in entry
More information about the pytest-commit
mailing list