[svn r58308] * de-generalize conditional skips and only care
nicely for common tedious causes of skipping: import a module and checking it has a certain version. usage example: docutils = py.test.importorskip(docutils, minversion="0.4") * used new helper and cleanup skipping logic in py lib --HG-- branch : trunk
This commit is contained in:
parent
fa5c975c00
commit
cc10d84088
|
@ -1,11 +1,10 @@
|
|||
$Id: CHANGELOG 58297 2008-09-21 12:50:56Z hpk $
|
||||
$Id: CHANGELOG 58308 2008-09-21 15:15:28Z hpk $
|
||||
|
||||
Changes between 0.9.2 and 1.0 (UNRELEASED)
|
||||
=============================================
|
||||
|
||||
* py.test.skip(ifraises=execstring) allows to
|
||||
conditionally skip, e.g. ifraises="import docutils"
|
||||
will skip if there is no docutils installed.
|
||||
* new method: py.test.importorskip(mod,minversion)
|
||||
will either import or call py.test.skip()
|
||||
|
||||
* revised internal py.test architecture
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ version = "1.0.0a1"
|
|||
|
||||
initpkg(__name__,
|
||||
description = "pylib and py.test: agile development and test support library",
|
||||
revision = int('$LastChangedRevision: 58190 $'.split(':')[1][:-1]),
|
||||
lastchangedate = '$LastChangedDate: 2008-09-17 10:50:04 +0200 (Wed, 17 Sep 2008) $',
|
||||
revision = int('$LastChangedRevision: 58308 $'.split(':')[1][:-1]),
|
||||
lastchangedate = '$LastChangedDate: 2008-09-21 17:15:28 +0200 (Sun, 21 Sep 2008) $',
|
||||
version = version,
|
||||
url = "http://pylib.org",
|
||||
download_url = "http://codespeak.net/py/0.9.2/download.html",
|
||||
|
@ -67,6 +67,7 @@ initpkg(__name__,
|
|||
'test.raises' : ('./test/outcome.py', 'raises'),
|
||||
'test.deprecated_call' : ('./test/outcome.py', 'deprecated_call'),
|
||||
'test.skip' : ('./test/outcome.py', 'skip'),
|
||||
'test.importorskip' : ('./test/outcome.py', 'importorskip'),
|
||||
'test.fail' : ('./test/outcome.py', 'fail'),
|
||||
'test.exit' : ('./test/outcome.py', 'exit'),
|
||||
'test.pdb' : ('./test/custompdb.py', 'set_trace'),
|
||||
|
|
|
@ -61,10 +61,7 @@ def deindent(s, sep='\n'):
|
|||
_initialized = False
|
||||
def checkdocutils():
|
||||
global _initialized
|
||||
try:
|
||||
import docutils
|
||||
except ImportError:
|
||||
py.test.skip("docutils not importable")
|
||||
py.test.importorskip("docutils")
|
||||
if not _initialized:
|
||||
from py.__.rest import directive
|
||||
directive.register_linkrole('api', resolve_linkrole)
|
||||
|
|
|
@ -90,20 +90,17 @@ Skipping tests
|
|||
----------------------------------------
|
||||
|
||||
If you want to skip tests you can use ``py.test.skip`` within
|
||||
test or setup functions. Examples::
|
||||
test or setup functions. Example::
|
||||
|
||||
py.test.skip("message")
|
||||
py.test.skip(ifraises="import docutils")
|
||||
py.test.skip(ifraises="""
|
||||
import somepkg
|
||||
assert somepkg.__version__.startswith("2")
|
||||
""")
|
||||
|
||||
The first skip will cause unconditional skipping
|
||||
The second skip will only cause skipping if
|
||||
``docutils`` is not importable.
|
||||
The third form will cause skipping if ``somepkg``
|
||||
is not importable or is not at least version "2".
|
||||
You can also use a helper to skip on a failing import::
|
||||
|
||||
docutils = py.test.importorskip("docutils")
|
||||
|
||||
or to skip if the library does not have the right version::
|
||||
|
||||
docutils = py.test.importorskip("docutils", minversion="0.3")
|
||||
|
||||
automatic collection of tests on all levels
|
||||
-------------------------------------------
|
||||
|
|
|
@ -181,7 +181,7 @@ class LocalPath(common.FSPathBase, PlatformMixin):
|
|||
break
|
||||
for arg in strargs:
|
||||
arg = arg.strip(sep)
|
||||
if py.std.sys.platform == 'win32':
|
||||
if iswin32:
|
||||
# allow unix style paths even on windows.
|
||||
arg = arg.strip('/')
|
||||
arg = arg.replace('/', sep)
|
||||
|
@ -512,7 +512,7 @@ class LocalPath(common.FSPathBase, PlatformMixin):
|
|||
if p.check(file=1):
|
||||
return p
|
||||
else:
|
||||
if py.std.sys.platform == 'win32':
|
||||
if iswin32:
|
||||
paths = py.std.os.environ['Path'].split(';')
|
||||
try:
|
||||
systemroot = os.environ['SYSTEMROOT']
|
||||
|
|
|
@ -7,6 +7,13 @@ from py.__.path.svn import cache, svncommon
|
|||
mypath = py.magic.autopath()
|
||||
repodump = mypath.dirpath('repotest.dump')
|
||||
|
||||
def getsvnbin():
|
||||
svnbin = py.path.local.sysfind('svn')
|
||||
if svnbin is None:
|
||||
py.test.skip("svn binary not found")
|
||||
return svnbin
|
||||
|
||||
|
||||
# make a wc directory out of a given root url
|
||||
# cache previously obtained wcs!
|
||||
#
|
||||
|
|
|
@ -95,6 +95,7 @@ class svnwc_no_svn(py.path.svnwc):
|
|||
class TestSvnWCAuth(object):
|
||||
def setup_method(self, meth):
|
||||
self.auth = SvnAuth('user', 'pass', cache_auth=False)
|
||||
svntestbase.getsvnbin()
|
||||
|
||||
def test_checkout(self):
|
||||
wc = svnwc_no_svn('foo', auth=self.auth)
|
||||
|
@ -250,6 +251,7 @@ class TestSvnURLAuth(object):
|
|||
|
||||
class SvnAuthFunctionalTestBase(object):
|
||||
def setup_class(cls):
|
||||
svntestbase.getsvnbin()
|
||||
if not option.runslowtests:
|
||||
py.test.skip('skipping slow functional tests - use --runslowtests '
|
||||
'to override')
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import py
|
||||
from py.__.path.svn.testing.svntestbase import make_test_repo
|
||||
from py.__.path.svn.testing.svntestbase import make_test_repo, getsvnbin
|
||||
|
||||
|
||||
if py.path.local.sysfind('svn') is None:
|
||||
py.test.skip("cannot test py.path.svn, 'svn' binary not found")
|
||||
|
||||
class TestMakeRepo(object):
|
||||
def setup_class(cls):
|
||||
getsvnbin()
|
||||
cls.repo = make_test_repo()
|
||||
cls.wc = py.path.svnwc(py.test.ensuretemp("test-wc").join("wc"))
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import py
|
||||
from py.__.path.svn.urlcommand import InfoSvnCommand
|
||||
from py.__.path.svn.testing.svntestbase import CommonCommandAndBindingTests, \
|
||||
getrepowc
|
||||
getrepowc, getsvnbin
|
||||
import datetime
|
||||
import time
|
||||
|
||||
def setup_module(mod):
|
||||
if py.path.local.sysfind('svn') is None:
|
||||
py.test.skip("cannot test py.path.svn, 'svn' binary not found")
|
||||
getsvnbin()
|
||||
|
||||
class TestSvnURLCommandPath(CommonCommandAndBindingTests):
|
||||
def setup_class(cls):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import py
|
||||
import sys
|
||||
from py.__.path.svn.testing.svntestbase import CommonSvnTests, getrepowc
|
||||
from py.__.path.svn.testing.svntestbase import CommonSvnTests, getrepowc, getsvnbin
|
||||
from py.__.path.svn.wccommand import InfoSvnWCCommand, XMLWCStatus
|
||||
from py.__.path.svn.wccommand import parse_wcinfotime
|
||||
from py.__.path.svn import svncommon
|
||||
|
@ -22,8 +22,7 @@ else:
|
|||
return os.path.normpath(os.path.normcase(p))
|
||||
|
||||
def setup_module(mod):
|
||||
if py.path.local.sysfind('svn') is None:
|
||||
py.test.skip("cannot test py.path.svn, 'svn' binary not found")
|
||||
getsvnbin()
|
||||
|
||||
class TestWCSvnCommandPath(CommonSvnTests):
|
||||
def setup_class(cls):
|
||||
|
|
|
@ -8,3 +8,4 @@ def getdata():
|
|||
tmpdir = py.test.ensuretemp(rel.replace(pydir.sep, '_'))
|
||||
mydatadir.copy(tmpdir)
|
||||
return tmpdir
|
||||
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
import py
|
||||
try:
|
||||
import docutils
|
||||
except ImportError:
|
||||
py.test.skip("docutils not present")
|
||||
|
||||
from py.__.rest.testing.setup import getdata
|
||||
docutils = py.test.importorskip("docutils")
|
||||
from py.__.rest import directive
|
||||
from py.__.misc import rest
|
||||
from py.__.rest.latex import process_rest_file
|
||||
from py.__.rest.testing.setup import getdata
|
||||
|
||||
def setup_module(mod):
|
||||
mod.datadir = getdata()
|
||||
|
|
|
@ -4,16 +4,13 @@ import py
|
|||
from py.__.misc import rest
|
||||
from py.__.rest.testing.setup import getdata
|
||||
|
||||
|
||||
def setup_module(mod):
|
||||
py.test.importorskip("docutils")
|
||||
if not py.path.local.sysfind("gs") or \
|
||||
not py.path.local.sysfind("dot") or \
|
||||
not py.path.local.sysfind("latex"):
|
||||
py.test.skip("ghostscript, graphviz and latex needed")
|
||||
try:
|
||||
import docutils
|
||||
except ImportError:
|
||||
py.test.skip("docutils not present")
|
||||
|
||||
mod.datadir = getdata()
|
||||
|
||||
def test_process_simple():
|
||||
|
|
|
@ -4,11 +4,7 @@ import py
|
|||
from py.__.rest.latex import process_configfile, process_rest_file
|
||||
from py.__.rest.testing.setup import getdata
|
||||
|
||||
try:
|
||||
import docutils
|
||||
except ImportError:
|
||||
py.test.skip("docutils not present")
|
||||
|
||||
docutils = py.test.importorskip("docutils")
|
||||
|
||||
def setup_module(mod):
|
||||
if not py.path.local.sysfind("gs") or \
|
||||
|
|
|
@ -49,31 +49,30 @@ def exit(msg):
|
|||
__tracebackhide__ = True
|
||||
raise Exit(msg)
|
||||
|
||||
def skip(msg="", ifraises=None, ns=None):
|
||||
""" (conditionally) skip this test/module/conftest.
|
||||
|
||||
msg: use this message when skipping.
|
||||
ifraises:
|
||||
if "exec ifraises in {'py': py}" raises an exception
|
||||
skip this test.
|
||||
ns: use this namespace when executing ifraises
|
||||
"""
|
||||
def skip(msg=""):
|
||||
""" skip with the given message. """
|
||||
__tracebackhide__ = True
|
||||
if ifraises is not None:
|
||||
ifraises = py.code.Source(ifraises).compile()
|
||||
if ns is None:
|
||||
ns = {}
|
||||
try:
|
||||
exec ifraises in ns
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except Exception, e:
|
||||
if not msg:
|
||||
msg = repr(e)
|
||||
else:
|
||||
return
|
||||
raise Skipped(msg=msg)
|
||||
|
||||
def importorskip(modname, minversion=None):
|
||||
""" return imported module or skip() """
|
||||
compile(modname, '', 'eval') # to catch syntaxerrors
|
||||
try:
|
||||
mod = __import__(modname)
|
||||
except ImportError:
|
||||
py.test.skip("could not import %r" %(modname,))
|
||||
if minversion is None:
|
||||
return mod
|
||||
verattr = getattr(mod, '__version__', None)
|
||||
if isinstance(minversion, str):
|
||||
minver = minversion.split(".")
|
||||
else:
|
||||
minver = list(minversion)
|
||||
if verattr is None or verattr.split(".") < minver:
|
||||
py.test.skip("module %r has __version__ %r, required is: %r" %(
|
||||
modname, verattr, minversion))
|
||||
return mod
|
||||
|
||||
def fail(msg="unknown failure"):
|
||||
""" fail with the given Message. """
|
||||
__tracebackhide__ = True
|
||||
|
|
|
@ -387,7 +387,7 @@ class TestPyTest(AcceptBase):
|
|||
|
||||
class TestInteractive(AcceptBase):
|
||||
def getspawn(self):
|
||||
py.test.skip(ifraises="import pexpect", ns=globals())
|
||||
pexpect = py.test.importorskip("pexpect")
|
||||
def spawn(cmd):
|
||||
return pexpect.spawn(cmd, logfile=self.tmpdir.join("spawn.out").open("w"))
|
||||
return spawn
|
||||
|
|
|
@ -59,33 +59,25 @@ def test_deprecated_explicit_call():
|
|||
py.test.deprecated_call(dep_explicit, 0)
|
||||
py.test.deprecated_call(dep_explicit, 0)
|
||||
|
||||
|
||||
|
||||
def test_skip_simple():
|
||||
excinfo = py.test.raises(Skipped, 'py.test.skip("xxx")')
|
||||
assert excinfo.traceback[-1].frame.code.name == "skip"
|
||||
assert excinfo.traceback[-1].ishidden()
|
||||
|
||||
def test_skip_ifraises():
|
||||
excinfo = py.test.raises(Skipped, '''
|
||||
py.test.skip(ifraises="""
|
||||
import lky
|
||||
""")
|
||||
''')
|
||||
assert excinfo.traceback[-1].frame.code.name == "skip"
|
||||
assert excinfo.traceback[-1].ishidden()
|
||||
assert excinfo.value.msg.startswith("ImportError")
|
||||
|
||||
def test_skip_ifraises_ns():
|
||||
d = {}
|
||||
py.test.skip(ns=d, ifraises="import py")
|
||||
assert d['py'] == py
|
||||
|
||||
def test_skip_ifraises_syntaxerror():
|
||||
def test_importorskip():
|
||||
try:
|
||||
excinfo = py.test.raises(SyntaxError, '''
|
||||
py.test.skip(ifraises="x y z")''')
|
||||
sys = py.test.importorskip("sys")
|
||||
assert sys == py.std.sys
|
||||
#path = py.test.importorskip("os.path")
|
||||
#assert path == py.std.os.path
|
||||
py.test.raises(Skipped, "py.test.importorskip('alskdj')")
|
||||
py.test.raises(SyntaxError, "py.test.importorskip('x y z')")
|
||||
py.test.raises(SyntaxError, "py.test.importorskip('x=y')")
|
||||
path = py.test.importorskip("py", minversion=".".join(py.__version__))
|
||||
py.test.raises(Skipped, """
|
||||
py.test.importorskip("py", minversion="5.0")
|
||||
""")
|
||||
except Skipped:
|
||||
py.test.fail("should not skip")
|
||||
assert not excinfo.traceback[-1].ishidden()
|
||||
print py.code.ExceptionInfo()
|
||||
py.test.fail("spurious skip")
|
||||
|
||||
|
|
Loading…
Reference in New Issue