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:
parent
1b6391d814
commit
56a936993c
|
@ -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.
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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 ""
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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*"])
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue