[py-svn] commit/pytest: 2 new changesets

Bitbucket commits-noreply at bitbucket.org
Sat Mar 5 14:16:34 CET 2011


2 new changesets in pytest:

http://bitbucket.org/hpk42/pytest/changeset/1eb351cf53d9/
changeset:   r2168:1eb351cf53d9
user:        hpk42
date:        2011-03-05 13:08:43
summary:     improve and clarify skipping docs
affected #:  2 files (1.1 KB)

--- a/ISSUES.txt	Sat Mar 05 12:11:35 2011 +0100
+++ b/ISSUES.txt	Sat Mar 05 13:08:43 2011 +0100
@@ -88,6 +88,16 @@
 on common spellings for operating systems and python
 interpreter versions.
 
+pytest.mark.xfail signature change
+-------------------------------------------------------
+tags: feature 2.1
+
+change to pytest.mark.xfail(reason, (optional)condition)
+to better implement the word meaning.  It also signals
+better that we always have some kind of an implementation
+reason that can be formualated.
+Compatibility? Maybe rename to "pytest.mark.xfail"?
+
 introduce py.test.mark registration
 -----------------------------------------
 tags: feature 2.1


--- a/doc/skipping.txt	Sat Mar 05 12:11:35 2011 +0100
+++ b/doc/skipping.txt	Sat Mar 05 13:08:43 2011 +0100
@@ -1,20 +1,22 @@
-
 .. _`skip and xfail`:
 
-skip and xfail mechanisms
+skip and xfail: dealing with tests that can not succeed
 =====================================================================
 
-You can skip or "xfail" test functions, either by marking functions
-with a decorator or by calling the ``pytest.skip|xfail`` functions.
+If you have test functions that cannot be run on certain platforms
+or that you expect to fail you can mark them accordingly or you
+may call helper functions during execution of setup or test functions.
 
-A *skip* means that you expect your test to pass unless a certain configuration or condition (e.g. wrong Python interpreter, missing dependency) prevents it to run.  And *xfail* means that you expect your test to fail because there is an
-implementation problem.  py.test counts and lists *xfailing* tests separately
-and it is possible to give additional information, such as bug number or a URL.
+A *skip* means that you expect your test to pass unless a certain
+configuration or condition (e.g. wrong Python interpreter, missing
+dependency) prevents it to run.  And *xfail* means that your test
+can run but you expect it to fail because there is an implementation problem.
 
-Detailed information about skipped/xfailed tests is by default not shown
-at the end of a test run to avoid cluttering the output.  You can use
-the ``-r`` option to see details corresponding to the "short" letters
-shown in the test progress::
+py.test counts and lists *skip* and *xfail* tests separately. However,
+detailed information about skipped/xfailed tests is not shown by default
+to avoid cluttering the output.  You can use the ``-r`` option to see
+details corresponding to the "short" letters shown in the test
+progress::
 
     py.test -rxs  # show extra info on skips and xfails
 
@@ -22,7 +24,7 @@
 
 .. _skipif:
 
-Skipping a single function
+Marking a test function to be skipped
 -------------------------------------------
 
 Here is an example of marking a test function to be skipped
@@ -34,9 +36,9 @@
         ...
 
 During test function setup the skipif condition is
-evaluated by calling ``eval(expr, namespace)``.  The namespace
-contains all the module globals of the test function so that
-you can for example check for versions::
+evaluated by calling ``eval('sys.version_info >= (3,0)', namespace)``.
+(*New in version 2.0.2*) The namespace contains all the module globals of the test function so that
+you can for example check for versions of a module you are using::
 
     import mymodule
 
@@ -44,23 +46,15 @@
     def test_function():
         ...
   
-The test function will be skipped and not run if
-mymodule is below the specified version.  The reason
+The test function will not be run ("skipped") if
+``mymodule`` is below the specified version.  The reason
 for specifying the condition as a string is mainly that
-you can see more detailed reporting of xfail/skip reasons.
+py.test can report a summary of skip conditions.
+For information on the construction of the ``namespace``
+see `evaluation of skipif/xfail conditions`_.
 
-Actually, the namespace is first initialized by
-putting the ``sys`` and ``os`` modules and the test
-``config`` object into it.  And is then updated with
-the module globals.  The latter allows you to skip based
-on a test configuration value::
-
-    @pytest.mark.skipif("not config.getvalue('db')")
-    def test_function(...):
-        ...
-
-You can create a shortcut for your conditional skip decorator
-at module level like this::
+You can of course create a shortcut for your conditional skip
+decorator at module level like this::
 
     win32only = pytest.mark.skipif("sys.platform != 'win32'")
 
@@ -68,11 +62,10 @@
     def test_function():
         ...
 
-
 skip all test functions of a class
 --------------------------------------
 
-As with all function :ref:`mark` you can skip test functions at the
+As with all function :ref:`marking <mark>` you can skip test functions at the
 `whole class- or module level`_.  Here is an example
 for skipping all methods of a test class based on the platform::
 
@@ -82,9 +75,10 @@
         def test_function(self):
             "will not be setup or run under 'win32' platform"
 
-The ``pytestmark`` decorator will be applied to each test function.
-If your code targets python2.6 or above you can equivalently use
-the skipif decorator on classes::
+The ``pytestmark`` special name tells py.test to apply it to each test
+function in the class.  If your code targets python2.6 or above you can
+more naturally use the skipif decorator (and any other marker) on
+classes::
 
     @pytest.mark.skipif("sys.platform == 'win32'")
     class TestPosixCalls:
@@ -155,6 +149,31 @@
     
     ======================== 6 xfailed in 0.06 seconds =========================
 
+.. _`evaluation of skipif/xfail conditions`:
+
+evaluation of skipif/xfail expressions
+----------------------------------------------------
+
+.. versionadded:: 2.0.2
+
+The evaluation of a condition string in ``pytest.mark.skipif(conditionstring)``
+or ``pytest.mark.xfail(conditionstring)`` takes place in a namespace
+dictionary which is constructed as follows:
+
+* the namespace is initialized by putting the ``sys`` and ``os`` modules
+  and the pytest ``config`` object into it.
+  
+* updated with the module globals of the test function for which the
+  expression is applied.
+
+The pytest ``config`` object allows you to skip based on a test configuration value
+which you might have added::
+
+    @pytest.mark.skipif("not config.getvalue('db')")
+    def test_function(...):
+        ...
+
+
 imperative xfail from within a test or setup function
 ------------------------------------------------------
 


http://bitbucket.org/hpk42/pytest/changeset/02a623da9d67/
changeset:   r2169:02a623da9d67
user:        hpk42
date:        2011-03-05 14:16:27
summary:     avoid deprecation warnings for our internal accesses
affected #:  4 files (525 bytes)

--- a/CHANGELOG	Sat Mar 05 13:08:43 2011 +0100
+++ b/CHANGELOG	Sat Mar 05 14:16:27 2011 +0100
@@ -32,6 +32,8 @@
 - fixed typos in the docs (thanks Victor Garcia, Brianna Laugher) and particular
   thanks to Laura Creighton who also revieved parts of the documentation.
 
+- more precise (avoiding of) deprecation warnings for node.Class|Function accesses
+
 Changes between 2.0.0 and 2.0.1
 ----------------------------------------------
 


--- a/_pytest/main.py	Sat Mar 05 13:08:43 2011 +0100
+++ b/_pytest/main.py	Sat Mar 05 14:16:27 2011 +0100
@@ -121,9 +121,6 @@
 
 def compatproperty(name):
     def fget(self):
-        #print "retrieving %r property from %s" %(name, self.fspath)
-        py.log._apiwarn("2.0", "use pytest.%s for "
-            "test collection and item classes" % name)
         return getattr(pytest, name)
     return property(fget, None, None,
         "deprecated attribute %r, use pytest.%s" % (name,name))
@@ -157,6 +154,14 @@
     File = compatproperty("File")
     Item = compatproperty("Item")
 
+    def _getcustomclass(self, name):
+        cls = getattr(self, name)
+        if cls != getattr(pytest, name):
+            py.log._apiwarn("2.0", "use of node.%s is deprecated, "
+                "use pytest_pycollect_makeitem(...) to create custom "
+                "collection nodes" % name)
+        return cls
+
     def __repr__(self):
         return "<%s %r>" %(self.__class__.__name__, getattr(self, 'name', None))
 


--- a/_pytest/python.py	Sat Mar 05 13:08:43 2011 +0100
+++ b/_pytest/python.py	Sat Mar 05 14:16:27 2011 +0100
@@ -73,7 +73,8 @@
     if collector._istestclasscandidate(name, obj):
         #if hasattr(collector.obj, 'unittest'):
         #    return # we assume it's a mixin class for a TestCase derived one
-        return collector.Class(name, parent=collector)
+        Class = collector._getcustomclass("Class")
+        return Class(name, parent=collector)
     elif collector.funcnamefilter(name) and hasattr(obj, '__call__'):
         if is_generator(obj):
             return Generator(name, parent=collector)
@@ -213,16 +214,18 @@
             extra.append(cls())
         plugins = self.getplugins() + extra
         gentesthook.pcall(plugins, metafunc=metafunc)
+        Function = self._getcustomclass("Function")
         if not metafunc._calls:
-            return self.Function(name, parent=self)
+            return Function(name, parent=self)
         l = []
         for callspec in metafunc._calls:
             subname = "%s[%s]" %(name, callspec.id)
-            function = self.Function(name=subname, parent=self,
+            function = Function(name=subname, parent=self,
                 callspec=callspec, callobj=funcobj, keywords={callspec.id:True})
             l.append(function)
         return l
 
+
 class Module(pytest.File, PyCollectorMixin):
     def _getobj(self):
         return self._memoizedcall('_obj', self._importtestmodule)
@@ -272,7 +275,7 @@
 class Class(PyCollectorMixin, pytest.Collector):
 
     def collect(self):
-        return [self.Instance(name="()", parent=self)]
+        return [self._getcustomclass("Instance")(name="()", parent=self)]
 
     def setup(self):
         setup_class = getattr(self.obj, 'setup_class', None)


--- a/testing/test_collection.py	Sat Mar 05 13:08:43 2011 +0100
+++ b/testing/test_collection.py	Sat Mar 05 14:16:27 2011 +0100
@@ -15,15 +15,10 @@
         """)
         recwarn.clear()
         assert modcol.Module == pytest.Module
-        recwarn.pop(DeprecationWarning)
         assert modcol.Class == pytest.Class
-        recwarn.pop(DeprecationWarning)
         assert modcol.Item == pytest.Item
-        recwarn.pop(DeprecationWarning)
         assert modcol.File == pytest.File
-        recwarn.pop(DeprecationWarning)
         assert modcol.Function == pytest.Function
-        recwarn.pop(DeprecationWarning)
 
     def test_check_equality(self, testdir):
         modcol = testdir.getmodulecol("""

Repository URL: https://bitbucket.org/hpk42/pytest/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.



More information about the pytest-commit mailing list