enhance figleaf setup, enabled by default now (requires --figleaf). Generalize internal ability to show "hints" at the end of "-h".

--HG--
branch : trunk
This commit is contained in:
holger krekel 2010-01-02 22:48:53 +01:00
parent 1b6391d814
commit 56a936993c
10 changed files with 58 additions and 47 deletions

View File

@ -40,6 +40,10 @@ Changes between 1.X and 1.1.1
- change: the first pytest_collect_directory hook to return something
will now prevent further hooks to be called.
- change: pytest figleaf now requires --figleaf to run and is turned
on by default (requires the 'figleaf' package though). Change
long command line options to be a bit shorter (see py.test -h).
- robustify capturing to survive if custom pytest_runtest_setup
code failed and prevented the capturing setup code from running.

View File

@ -92,6 +92,7 @@ class Config(object):
assert not hasattr(self, 'args'), (
"can only parse cmdline args at most once per Config object")
self._preparse(args)
self._parser.hints.extend(self.pluginmanager._hints)
args = self._parser.parse_setoption(args, self.option)
if not args:
args.append(py.std.os.getcwd())

View File

@ -24,7 +24,7 @@ class Parser:
self._groups = []
self._processopt = processopt
self._usage = usage
self.epilog = ""
self.hints = []
def processoption(self, option):
if self._processopt:
@ -56,9 +56,7 @@ class Parser:
self._anonymous.addoption(*opts, **attrs)
def parse(self, args):
optparser = optparse.OptionParser(usage=self._usage)
# make sure anaonymous group is at the end
optparser.epilog = self.epilog
optparser = MyOptionParser(self)
groups = self._groups + [self._anonymous]
for group in groups:
if group.options:
@ -100,4 +98,15 @@ class OptionGroup:
self.parser.processoption(option)
self.options.append(option)
class MyOptionParser(optparse.OptionParser):
def __init__(self, parser):
self._parser = parser
optparse.OptionParser.__init__(self, usage=parser._usage)
def format_epilog(self, formatter):
hints = self._parser.hints
if hints:
s = "\n".join(["hint: " + x for x in hints]) + "\n"
s = "\n" + s + "\n"
return s
return ""

View File

@ -9,7 +9,7 @@ from py.impl.test.outcome import Skipped
default_plugins = (
"default runner capture terminal mark skipping tmpdir monkeypatch "
"recwarn pdb pastebin unittest helpconfig nose assertion genscript "
"logxml").split()
"logxml figleaf").split()
def check_old_use(mod, modname):
clsname = modname[len('pytest_'):].capitalize() + "Plugin"
@ -19,10 +19,11 @@ class PluginManager(object):
def __init__(self):
self.registry = Registry()
self._name2plugin = {}
self._hints = []
self.hook = HookRelay(hookspecs=hookspec, registry=self.registry)
self.register(self)
for spec in default_plugins:
self.import_plugin(spec)
self.import_plugin(spec)
def _getpluginname(self, plugin, name):
if name is None:
@ -123,15 +124,17 @@ class PluginManager(object):
raise
except Skipped:
e = py.std.sys.exc_info()[1]
self._warn("could not import plugin %r, reason: %r" %(
(modname, e.msg)))
self._hints.append("skipped plugin %r: %s" %((modname, e.msg)))
else:
check_old_use(mod, modname)
self.register(mod)
self.consider_module(mod)
def _warn(self, msg):
print ("===WARNING=== %s" % (msg,))
def pytest_terminal_summary(self, terminalreporter):
tw = terminalreporter._tw
if terminalreporter.config.option.traceconfig:
for hint in self._hints:
tw.line("hint: %s" % hint)
#
#
@ -201,10 +204,8 @@ def importplugin(importspec):
e = py.std.sys.exc_info()[1]
if str(e).find(importspec) == -1:
raise
#print "syspath:", py.std.sys.path
#print "curdir:", py.std.os.getcwd()
return __import__(importspec) # show the original exception
# show the original exception, not the failing internal one
return __import__(importspec)
class MultiCall:

View File

@ -80,8 +80,9 @@ def pytest_addoption(parser):
if execnet:
add_dist_options(parser)
else:
parser.epilog = (
"'execnet>=1.0.0b4' package required for --looponfailing / distributed testing.")
parser.hints.append(
"'execnet>=1.0.0b4' required for --looponfailing / distributed testing."
)
def add_dist_options(parser):
# see http://pytest.org/help/dist")

View File

@ -18,7 +18,7 @@ from py.impl.code.code import TerminalRepr, ReprFileLocation
import doctest
def pytest_addoption(parser):
group = parser.getgroup("doctest options")
group = parser.getgroup("general")
group.addoption("--doctest-modules",
action="store_true", default=False,
help="search all python files for doctests",

View File

@ -3,28 +3,30 @@ write and report coverage data with 'figleaf'.
"""
import py
py.test.importorskip("figleaf.annotate_html")
import figleaf
py.test.importorskip("figleaf")
import figleaf.annotate_html
def pytest_addoption(parser):
group = parser.getgroup('figleaf options')
group.addoption('-F', action='store_true', default=False,
group.addoption('--figleaf', action='store_true', default=False,
dest = 'figleaf',
help=('trace python coverage with figleaf and write HTML '
'for files below the current working dir'))
group.addoption('--figleaf-data', action='store', default='.figleaf',
dest='figleafdata',
help='path to coverage tracing file.')
group.addoption('--figleaf-html', action='store', default='html',
dest='figleafhtml',
help='path to the coverage html dir.')
group.addoption('--fig-data', action='store', default='.figleaf',
dest='figleafdata', metavar="dir",
help='set tracing file, default: ".figleaf".')
group.addoption('--fig-html', action='store', default='html',
dest='figleafhtml', metavar="dir",
help='set html reporting dir, default "html").')
def pytest_configure(config):
figleaf.start()
if config.getvalue("figleaf"):
figleaf.start()
def pytest_terminal_summary(terminalreporter):
config = terminalreporter.config
if not config.getvalue("figleaf"):
return
datafile = py.path.local(config.getvalue('figleafdata'))
tw = terminalreporter._tw
tw.sep('-', 'figleaf')

View File

@ -2,16 +2,16 @@ import py
def test_functional(testdir):
py.test.importorskip("figleaf")
testdir.plugins.append("figleaf")
testdir.makepyfile("""
def f():
x = 42
def test_whatever():
pass
""")
result = testdir.runpytest('-F')
result = testdir.runpytest('--figleaf')
assert result.ret == 0
assert result.stdout.fnmatch_lines([
'*figleaf html*'
])
#print result.stdout.str()

View File

@ -8,12 +8,6 @@ class TestParser:
out, err = capsys.readouterr()
assert out.find("xyz") != -1
def test_epilog(self):
parser = parseopt.Parser()
assert not parser.epilog
parser.epilog += "hello"
assert parser.epilog == "hello"
def test_group_add_and_get(self):
parser = parseopt.Parser()
group = parser.addgroup("hello", description="desc")
@ -117,9 +111,9 @@ class TestParser:
def test_addoption_parser_epilog(testdir):
testdir.makeconftest("""
def pytest_addoption(parser):
parser.epilog = "hello world"
parser.hints.append("hello world")
""")
result = testdir.runpytest('--help')
#assert result.ret != 0
assert result.stdout.fnmatch_lines(["*hello world*"])
assert result.stdout.fnmatch_lines(["*hint: hello world*"])

View File

@ -16,18 +16,17 @@ class TestBootstrapping:
""")
def test_plugin_skip(self, testdir, monkeypatch):
testdir.makepyfile(pytest_skipping1="""
p = testdir.makepyfile(pytest_skipping1="""
import py
py.test.skip("hello")
""")
result = testdir.runpytest("-p", "skipping1")
p.copy(p.dirpath("pytest_skipping2.py"))
monkeypatch.setenv("PYTEST_PLUGINS", "skipping2")
result = testdir.runpytest("-p", "skipping1", "--traceconfig")
assert result.ret == 0
result.stdout.fnmatch_lines([
"*WARNING*could not import plugin*skipping1*hello*"
])
monkeypatch.setenv("PYTEST_PLUGINS", "skipping1")
result = testdir.runpytest()
result.stdout.fnmatch_lines([
"*WARNING*could not import plugin*skipping1*hello*"
"*hint*skipping2*hello*",
"*hint*skipping1*hello*",
])
def test_consider_env_plugin_instantiation(self, testdir, monkeypatch):