rename pocoo to "pastebin" plugin, write documentation, implement whole-session-pasting

--HG--
branch : 1.0.x
This commit is contained in:
holger krekel 2009-08-03 11:56:56 +02:00
parent b5115963ee
commit 96c863b3c1
11 changed files with 155 additions and 124 deletions

View File

@ -28,7 +28,7 @@ restdoc_ perform ReST syntax, local and remote reference tests on .rst/.txt file
Plugins for generic reporting and failure logging Plugins for generic reporting and failure logging
================================================= =================================================
pocoo_ submit failure information to paste.pocoo.org pastebin_ submit failure or test session information to a pastebin service.
resultlog_ resultlog plugin for machine-readable logging of test results. resultlog_ resultlog plugin for machine-readable logging of test results.

View File

@ -113,8 +113,8 @@ command line options
``-s`` ``-s``
shortcut for --capture=no. shortcut for --capture=no.
``--capture=capture`` ``--capture=method``
set IO capturing method during tests: sys|fd|no. set capturing method during tests: fd (default)|sys|no.
Start improving this plugin in 30 seconds Start improving this plugin in 30 seconds
========================================= =========================================

View File

@ -1,33 +1,33 @@
.. _`pytest_recwarn.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_recwarn.py .. _`pytest_recwarn.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_recwarn.py
.. _`pytest_iocapture.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_iocapture.py .. _`pytest_iocapture.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_iocapture.py
.. _`pytest_monkeypatch.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_monkeypatch.py .. _`pytest_monkeypatch.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_monkeypatch.py
.. _`pytest_keyword.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_keyword.py
.. _`pastebin`: pastebin.html
.. _`plugins`: index.html .. _`plugins`: index.html
.. _`pytest_doctest.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_doctest.py .. _`pytest_doctest.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_doctest.py
.. _`terminal`: terminal.html .. _`terminal`: terminal.html
.. _`hooklog`: hooklog.html .. _`hooklog`: hooklog.html
.. _`pytest_restdoc.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_restdoc.py .. _`pytest_restdoc.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_restdoc.py
.. _`pytest_hooklog.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_hooklog.py
.. _`pytest_pastebin.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_pastebin.py
.. _`pytest_figleaf.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_figleaf.py
.. _`xfail`: xfail.html .. _`xfail`: xfail.html
.. _`pytest_pocoo.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_pocoo.py
.. _`pytest_keyword.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_keyword.py
.. _`pytest_figleaf.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_figleaf.py
.. _`pytest_hooklog.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_hooklog.py
.. _`contact`: ../../contact.html .. _`contact`: ../../contact.html
.. _`pocoo`: pocoo.html
.. _`checkout the py.test development version`: ../../download.html#checkout .. _`checkout the py.test development version`: ../../download.html#checkout
.. _`oejskit`: oejskit.html .. _`oejskit`: oejskit.html
.. _`unittest`: unittest.html .. _`unittest`: unittest.html
.. _`iocapture`: iocapture.html .. _`iocapture`: iocapture.html
.. _`pytest_xfail.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_xfail.py .. _`pytest_xfail.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_xfail.py
.. _`figleaf`: figleaf.html .. _`figleaf`: figleaf.html
.. _`extend`: ../extend.html .. _`extend`: ../extend.html
.. _`pytest_terminal.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_terminal.py .. _`pytest_terminal.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_terminal.py
.. _`recwarn`: recwarn.html .. _`recwarn`: recwarn.html
.. _`pytest_pdb.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_pdb.py .. _`pytest_pdb.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_pdb.py
.. _`monkeypatch`: monkeypatch.html .. _`monkeypatch`: monkeypatch.html
.. _`resultlog`: resultlog.html .. _`resultlog`: resultlog.html
.. _`keyword`: keyword.html .. _`keyword`: keyword.html
.. _`restdoc`: restdoc.html .. _`restdoc`: restdoc.html
.. _`pytest_unittest.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_unittest.py .. _`pytest_unittest.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_unittest.py
.. _`doctest`: doctest.html .. _`doctest`: doctest.html
.. _`pytest_resultlog.py`: http://bitbucket.org/hpk42/py-trunk/raw/69bd12627e4d304c89c2003842703ccb10dfe838/py/test/plugin/pytest_resultlog.py .. _`pytest_resultlog.py`: http://bitbucket.org/hpk42/py-trunk/raw/6f105e72c160bd25ad7bbd4d30b1e4e92f275939/py/test/plugin/pytest_resultlog.py
.. _`pdb`: pdb.html .. _`pdb`: pdb.html

View File

@ -1,31 +0,0 @@
pytest_pocoo plugin
===================
submit failure information to paste.pocoo.org
.. contents::
:local:
command line options
--------------------
``-P, --pocoo-sendfailures``
send failures to http://paste.pocoo.org paste service
Start improving this plugin in 30 seconds
=========================================
Do you find the above documentation or the plugin itself lacking?
1. Download `pytest_pocoo.py`_ plugin source code
2. put it somewhere as ``pytest_pocoo.py`` into your import path
3. a subsequent ``py.test`` run will use your local version
Further information: extend_ documentation, other plugins_ or contact_.
.. include:: links.txt

View File

@ -9,7 +9,7 @@ plugins = [
('Plugins for other testing styles and languages', ('Plugins for other testing styles and languages',
'unittest doctest oejskit restdoc'), 'unittest doctest oejskit restdoc'),
('Plugins for generic reporting and failure logging', ('Plugins for generic reporting and failure logging',
'pocoo resultlog terminal',), 'pastebin resultlog terminal',),
('internal plugins / core functionality', ('internal plugins / core functionality',
'pdb keyword hooklog') 'pdb keyword hooklog')
#('internal plugins / core functionality', #('internal plugins / core functionality',

View File

@ -201,13 +201,8 @@ class TerminalWriter(object):
self._file.flush() self._file.flush()
def line(self, s='', **kw): def line(self, s='', **kw):
if s: self.write(s, **kw)
s = self.markup(s, **kw) self.write('\n')
self._file.write(s + '\n')
else:
self._file.write('\n')
self._file.flush()
class Win32ConsoleWriter(object): class Win32ConsoleWriter(object):

View File

@ -10,6 +10,6 @@ Generator = py.test.collect.Generator
Function = py.test.collect.Function Function = py.test.collect.Function
Instance = py.test.collect.Instance Instance = py.test.collect.Instance
pytest_plugins = "default runner iocapture terminal keyword xfail tmpdir execnetcleanup monkeypatch recwarn pdb unittest".split() pytest_plugins = "default runner iocapture terminal keyword xfail tmpdir execnetcleanup monkeypatch recwarn pdb pastebin unittest".split()
conf_capture = "fd" conf_capture = "fd"

View File

@ -89,8 +89,8 @@ def pytest_addoption(parser):
group._addoption('-s', action="store_const", const="no", dest="capture", group._addoption('-s', action="store_const", const="no", dest="capture",
help="shortcut for --capture=no.") help="shortcut for --capture=no.")
group._addoption('--capture', action="store", default=None, group._addoption('--capture', action="store", default=None,
metavar="capture", type="choice", choices=['fd', 'sys', 'no'], metavar="method", type="choice", choices=['fd', 'sys', 'no'],
help="set IO capturing method during tests: sys|fd|no.") help="set capturing method during tests: fd (default)|sys|no.")
def addouterr(rep, outerr): def addouterr(rep, outerr):
repr = getattr(rep, 'longrepr', None) repr = getattr(rep, 'longrepr', None)

View File

@ -0,0 +1,130 @@
"""
submit failure or test session information to a pastebin service.
Usage
----------
**Creating a URL for each test failure**::
py.test --pastebin=failed
This will submit full failure information to a remote Paste service and
provide a URL for each failure. You may select tests as usual or add
for example ``-x`` if you only want to send one particular failure.
**Creating a URL for a whole test session log**::
py.test --pastebin=all
Currently only pasting to the http://paste.pocoo.org service is implemented.
"""
import py, sys
class url:
base = "http://paste.pocoo.org"
xmlrpc = base + "/xmlrpc/"
show = base + "/show/"
def pytest_addoption(parser):
group = parser.getgroup("general")
group._addoption('--pastebin', metavar="mode",
action='store', dest="pastebin", default=None,
type="choice", choices=['failed', 'all'],
help="send failed|all info to Pocoo pastebin service.")
def pytest_configure(__call__, config):
import tempfile
__call__.execute()
if config.option.pastebin == "all":
config._pastebinfile = tempfile.TemporaryFile()
tr = config.pluginmanager.impname2plugin['terminalreporter']
oldwrite = tr._tw.write
def tee_write(s, **kwargs):
oldwrite(s, **kwargs)
config._pastebinfile.write(str(s))
tr._tw.write = tee_write
def pytest_unconfigure(config):
if hasattr(config, '_pastebinfile'):
config._pastebinfile.seek(0)
sessionlog = config._pastebinfile.read()
config._pastebinfile.close()
del config._pastebinfile
proxyid = getproxy().newPaste("python", sessionlog)
pastebinurl = "%s%s" % (url.show, proxyid)
print >>sys.stderr, "session-log:", pastebinurl
tr = config.pluginmanager.impname2plugin['terminalreporter']
del tr._tw.__dict__['write']
def getproxy():
return py.std.xmlrpclib.ServerProxy(url.xmlrpc).pastes
def pytest_terminal_summary(terminalreporter):
if terminalreporter.config.option.pastebin != "failed":
return
tr = terminalreporter
if 'failed' in tr.stats:
terminalreporter.write_sep("=", "Sending information to Paste Service")
if tr.config.option.debug:
terminalreporter.write_line("xmlrpcurl: %s" %(url.xmlrpc,))
serverproxy = getproxy()
for rep in terminalreporter.stats.get('failed'):
try:
msg = rep.longrepr.reprtraceback.reprentries[-1].reprfileloc
except AttributeError:
msg = tr._getfailureheadline(rep)
tw = py.io.TerminalWriter(stringio=True)
rep.toterminal(tw)
s = tw.stringio.getvalue()
assert len(s)
proxyid = serverproxy.newPaste("python", s)
pastebinurl = "%s%s" % (url.show, proxyid)
tr.write_line("%s --> %s" %(msg, pastebinurl))
class TestPasting:
def pytest_funcarg__pastebinlist(self, request):
mp = request.getfuncargvalue("monkeypatch")
pastebinlist = []
class MockProxy:
def newPaste(self, language, code):
pastebinlist.append((language, code))
mp.setitem(globals(), 'getproxy', MockProxy)
return pastebinlist
def test_failed(self, testdir, pastebinlist):
testpath = testdir.makepyfile("""
import py
def test_pass():
pass
def test_fail():
assert 0
def test_skip():
py.test.skip("")
""")
reprec = testdir.inline_run(testpath, "--paste=failed")
assert len(pastebinlist) == 1
assert pastebinlist[0][0] == "python"
s = pastebinlist[0][1]
assert s.find("def test_fail") != -1
assert reprec.countoutcomes() == [1,1,1]
def test_all(self, testdir, pastebinlist):
testpath = testdir.makepyfile("""
import py
def test_pass():
pass
def test_fail():
assert 0
def test_skip():
py.test.skip("")
""")
reprec = testdir.inline_run(testpath, "--pastebin=all")
assert reprec.countoutcomes() == [1,1,1]
assert len(pastebinlist) == 1
assert pastebinlist[0][0] == "python"
s = pastebinlist[0][1]
for x in 'test_fail test_skip skipped'.split():
assert s.find(x), (s, x)

View File

@ -1,63 +0,0 @@
"""
submit failure information to paste.pocoo.org
"""
import py
class url:
base = "http://paste.pocoo.org"
xmlrpc = base + "/xmlrpc/"
show = base + "/show/"
def pytest_addoption(parser):
group = parser.addgroup("pocoo plugin")
group.addoption('-P', '--pocoo-sendfailures',
action='store_true', dest="pocoo_sendfailures",
help="send failures to %s paste service" %(url.base,))
def getproxy():
return py.std.xmlrpclib.ServerProxy(url.xmlrpc).pastes
def pytest_terminal_summary(terminalreporter):
if terminalreporter.config.option.pocoo_sendfailures:
tr = terminalreporter
if 'failed' in tr.stats and tr.config.option.tbstyle != "no":
terminalreporter.write_sep("=", "Sending failures to %s" %(url.base,))
terminalreporter.write_line("xmlrpcurl: %s" %(url.xmlrpc,))
#print self.__class__.getproxy
#print self.__class__, id(self.__class__)
serverproxy = getproxy()
for ev in terminalreporter.stats.get('failed'):
tw = py.io.TerminalWriter(stringio=True)
ev.toterminal(tw)
s = tw.stringio.getvalue()
# XXX add failure summary
assert len(s)
terminalreporter.write_line("newpaste() ...")
proxyid = serverproxy.newPaste("python", s)
terminalreporter.write_line("%s%s\n" % (url.show, proxyid))
break
def test_toproxy(testdir, monkeypatch):
l = []
class MockProxy:
def newPaste(self, language, code):
l.append((language, code))
monkeypatch.setitem(globals(), 'getproxy', MockProxy)
testdir.plugins.insert(0, globals())
testpath = testdir.makepyfile("""
import py
def test_pass():
pass
def test_fail():
assert 0
def test_skip():
py.test.skip("")
""")
reprec = testdir.inline_run(testpath, "-P")
assert len(l) == 1
assert l[0][0] == "python"
s = l[0][1]
assert s.find("def test_fail") != -1
assert reprec.countoutcomes() == [1,1,1]

View File

@ -18,7 +18,7 @@ def pytest_configure(config):
name = attr.split("_")[-1] name = attr.split("_")[-1]
assert hasattr(self.reporter._tw, name), name assert hasattr(self.reporter._tw, name), name
setattr(reporter._tw, name, getattr(config, attr)) setattr(reporter._tw, name, getattr(config, attr))
config.pluginmanager.register(reporter) config.pluginmanager.register(reporter, 'terminalreporter')
class TerminalReporter: class TerminalReporter:
def __init__(self, config, file=None): def __init__(self, config, file=None):