[py-svn] r58297 - in py/trunk: . py/doc py/test py/test/testing

hpk at codespeak.net hpk at codespeak.net
Sun Sep 21 14:50:58 CEST 2008


Author: hpk
Date: Sun Sep 21 14:50:56 2008
New Revision: 58297

Modified:
   py/trunk/CHANGELOG
   py/trunk/py/doc/test.txt
   py/trunk/py/test/outcome.py
   py/trunk/py/test/testing/test_collect.py
   py/trunk/py/test/testing/test_outcome.py
Log:
add a new way of conditionally skipping a test:

    py.test.skip(ifraises="...")

see more info in the added doc.

also remove a redundant raises test and 
cleanup raises code a bit. 



Modified: py/trunk/CHANGELOG
==============================================================================
--- py/trunk/CHANGELOG	(original)
+++ py/trunk/CHANGELOG	Sun Sep 21 14:50:56 2008
@@ -3,7 +3,12 @@
 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. 
+
 * revised internal py.test architecture
+
 * new py.process.ForkedFunc object allowing to 
   fork execution of a function to a sub process
   and getting a result back. 

Modified: py/trunk/py/doc/test.txt
==============================================================================
--- py/trunk/py/doc/test.txt	(original)
+++ py/trunk/py/doc/test.txt	Sun Sep 21 14:50:56 2008
@@ -86,6 +86,24 @@
 provide you with helpful output in case of failures such as *no
 exception* or *wrong exception*.
 
+Skipping tests 
+----------------------------------------
+
+If you want to skip tests you can use ``py.test.skip`` within
+test or setup functions.  Examples::
+
+    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". 
 
 automatic collection of tests on all levels
 -------------------------------------------

Modified: py/trunk/py/test/outcome.py
==============================================================================
--- py/trunk/py/test/outcome.py	(original)
+++ py/trunk/py/test/outcome.py	Sun Sep 21 14:50:56 2008
@@ -49,9 +49,26 @@
     __tracebackhide__ = True
     raise Exit(msg)
 
-def skip(msg=""):
-    """ skip with the given Message. """
+def skip(msg="", ifraises=None):
+    """ (conditionally) skip this test/module/conftest. 
+       
+    ifraises: 
+        if "exec ifraises in {'py': py}" raises an exception 
+        skip this test. 
+    msg: use this message when skipping. 
+    """
     __tracebackhide__ = True
+    if ifraises is not None:
+        ifraises = py.code.Source(ifraises).compile()
+        try:
+            exec ifraises in {'py': py}
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except Exception, e:
+            if not msg:
+                msg = repr(e)
+        else:
+            return    
     raise Skipped(msg=msg) 
 
 def fail(msg="unknown failure"):
@@ -66,16 +83,15 @@
     __tracebackhide__ = True 
     assert args
     if isinstance(args[0], str):
-        expr, = args
-        assert isinstance(expr, str)
+        code, = args
+        assert isinstance(code, str)
         frame = sys._getframe(1)
         loc = frame.f_locals.copy()
         loc.update(kwargs)
         #print "raises frame scope: %r" % frame.f_locals
-        source = py.code.Source(expr)
         try:
-            exec source.compile() in frame.f_globals, loc
-            #del __traceback__
+            code = py.code.Source(code).compile()
+            exec code in frame.f_globals, loc
             # XXX didn'T mean f_globals == f_locals something special?
             #     this is destroyed here ...
         except ExpectedException:
@@ -85,7 +101,6 @@
         assert callable
         try:
             func(*args[1:], **kwargs)
-            #del __traceback__
         except ExpectedException:
             return py.code.ExceptionInfo()
         k = ", ".join(["%s=%r" % x for x in kwargs.items()])

Modified: py/trunk/py/test/testing/test_collect.py
==============================================================================
--- py/trunk/py/test/testing/test_collect.py	(original)
+++ py/trunk/py/test/testing/test_collect.py	Sun Sep 21 14:50:56 2008
@@ -427,29 +427,13 @@
         ev = failures[0] 
         assert ev.outcome.longrepr.reprcrash.message.startswith("SyntaxError")
 
-    def test_skip_at_module_level(self):
-        self.tmp.ensure("test_module.py").write(py.code.Source("""
-            import py
-            py.test.skip('xxx')
-        """))
-        items, events = self._genitems()
-        funcs = [x for x in items if isinstance(x, event.ItemStart)]
-        assert not funcs 
-        assert not items 
-        l = [x for x in events 
-                if isinstance(x, event.CollectionReport)
-                   and x.colitem.name == 'test_module.py']
-        assert len(l) == 1
-        ev = l[0]
-        assert ev.skipped 
-
     def test_example_items1(self):
         self.tmp.ensure("test_example.py").write(py.code.Source('''
-            def test_one():
+            def testone():
                 pass
 
             class TestX:
-                def test_method_one(self):
+                def testmethod_one(self):
                     pass
 
             class TestY(TestX):
@@ -457,17 +441,17 @@
         '''))
         items, events = self._genitems()
         assert len(items) == 3
-        assert items[0].name == 'test_one'
-        assert items[1].name == 'test_method_one'
-        assert items[2].name == 'test_method_one'
+        assert items[0].name == 'testone'
+        assert items[1].name == 'testmethod_one'
+        assert items[2].name == 'testmethod_one'
 
         # let's also test getmodpath here
-        assert items[0].getmodpath() == "test_one"
-        assert items[1].getmodpath() == "TestX.test_method_one"
-        assert items[2].getmodpath() == "TestY.test_method_one"
+        assert items[0].getmodpath() == "testone"
+        assert items[1].getmodpath() == "TestX.testmethod_one"
+        assert items[2].getmodpath() == "TestY.testmethod_one"
 
         s = items[0].getmodpath(stopatmodule=False)
-        assert s == "test_example_items1.test_example.test_one"
+        assert s == "test_example_items1.test_example.testone"
         print s
 
     def test_collect_doctest_files_with_test_prefix(self):

Modified: py/trunk/py/test/testing/test_outcome.py
==============================================================================
--- py/trunk/py/test/testing/test_outcome.py	(original)
+++ py/trunk/py/test/testing/test_outcome.py	Sun Sep 21 14:50:56 2008
@@ -1,6 +1,7 @@
 
 import py
 import marshal
+from py.__.test.outcome import Skipped
 
 class TestRaises:
     def test_raises(self):
@@ -58,3 +59,28 @@
     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_syntaxerror():
+    try:
+        excinfo = py.test.raises(SyntaxError, '''
+            py.test.skip(ifraises="x y z")''')
+    except Skipped:
+        py.test.fail("should not skip")
+    assert not excinfo.traceback[-1].ishidden()
+



More information about the pytest-commit mailing list