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

Bitbucket commits-noreply at bitbucket.org
Tue Sep 18 10:54:55 CEST 2012


2 new commits in pytest:


https://bitbucket.org/hpk42/pytest/changeset/bbd625a935b0/
changeset:   bbd625a935b0
user:        hpk42
date:        2012-09-18 10:53:42
summary:     remove distinction of new versus old funcarg factories
affected #:  1 file

diff -r 2bfd9f1d38e92844576df3e71fee49a76c208637 -r bbd625a935b068c1e37f2273f79cdc4bdc1b4cee _pytest/python.py
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -1363,12 +1363,10 @@
                 argname = name
                 scope = marker.scope
                 params = marker.params
-                new = True
             elif name.startswith(self._argprefix):
                 argname = name[len(self._argprefix):]
                 scope = None
                 params = None
-                new = False
             else:
                 # no funcargs. check if we have a setup function.
                 setup = getattr(obj, "_pytestsetup", None)
@@ -1378,8 +1376,7 @@
                     self.setuplist.append(sf)
                 continue
             faclist = self.arg2facspec.setdefault(argname, [])
-            factorydef = FactoryDef(self, nodeid, argname, obj, scope, params,
-                                    new)
+            factorydef = FactoryDef(self, nodeid, argname, obj, scope, params)
             faclist.append(factorydef)
             ### check scope/params mismatch?
 
@@ -1489,15 +1486,13 @@
 
 class FactoryDef:
     """ A container for a factory definition. """
-    def __init__(self, funcargmanager, baseid, argname, func, scope, params,
-                 new):
+    def __init__(self, funcargmanager, baseid, argname, func, scope, params):
         self.funcargmanager = funcargmanager
         self.baseid = baseid
         self.func = func
         self.argname = argname
         self.scope = scope
         self.params = params
-        self.new = new
         self.funcargnames = getfuncargnames(func)
 
 def getfuncargnames(function, startindex=None):



https://bitbucket.org/hpk42/pytest/changeset/93f393567640/
changeset:   93f393567640
user:        hpk42
date:        2012-09-18 10:54:12
summary:     implement full @pytest.setup function unittest.TestCase interaction
affected #:  7 files

diff -r bbd625a935b068c1e37f2273f79cdc4bdc1b4cee -r 93f393567640808a5c6166fe618adf38e37890d4 _pytest/__init__.py
--- a/_pytest/__init__.py
+++ b/_pytest/__init__.py
@@ -1,2 +1,2 @@
 #
-__version__ = '2.3.0.dev12'
+__version__ = '2.3.0.dev13'


diff -r bbd625a935b068c1e37f2273f79cdc4bdc1b4cee -r 93f393567640808a5c6166fe618adf38e37890d4 _pytest/python.py
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -1001,10 +1001,14 @@
         if clscol:
             return clscol.obj
 
-    @scopeproperty()
+    @property
     def instance(self):
         """ instance (can be None) on which test function was collected. """
-        return py.builtin._getimself(self.function)
+        # unittest support hack, see _pytest.unittest.TestCaseFunction
+        try:
+            return self._pyfuncitem._testcase
+        except AttributeError:
+            return py.builtin._getimself(self.function)
 
     @scopeproperty()
     def module(self):
@@ -1341,7 +1345,7 @@
                 for fin in l:
                     fin()
 
-    def _parsefactories(self, holderobj, nodeid):
+    def _parsefactories(self, holderobj, nodeid, unittest=False):
         if holderobj in self._holderobjseen:
             return
         #print "parsefactories", holderobj
@@ -1372,7 +1376,7 @@
                 setup = getattr(obj, "_pytestsetup", None)
                 if setup is not None:
                     scope = setup.scope
-                    sf = SetupCall(self, nodeid, obj, scope)
+                    sf = SetupCall(self, nodeid, obj, scope, unittest)
                     self.setuplist.append(sf)
                 continue
             faclist = self.arg2facspec.setdefault(argname, [])
@@ -1428,7 +1432,6 @@
             request._factorystack.append(setupcall)
             mp = monkeypatch()
             try:
-                #mp.setattr(request, "_setupcall", setupcall, raising=False)
                 mp.setattr(request, "scope", setupcall.scope)
                 kwargs = {}
                 for name in setupcall.funcargnames:
@@ -1438,7 +1441,12 @@
                 self.session._setupstate.addfinalizer(setupcall.finish, scol)
                 for argname in setupcall.funcargnames: # XXX all deps?
                     self.addargfinalizer(setupcall.finish, argname)
-                setupcall.execute(kwargs)
+                # for unittest-setup methods we need to provide
+                # the correct instance
+                posargs = ()
+                if setupcall.unittest:
+                    posargs = (request.instance,)
+                setupcall.execute(posargs, kwargs)
             finally:
                 mp.undo()
                 request._factorystack.remove(setupcall)
@@ -1457,20 +1465,21 @@
 
 class SetupCall:
     """ a container/helper for managing calls to setup functions. """
-    def __init__(self, funcargmanager, baseid, func, scope):
+    def __init__(self, funcargmanager, baseid, func, scope, unittest):
         self.funcargmanager = funcargmanager
         self.baseid = baseid
         self.func = func
-        self.funcargnames = getfuncargnames(func)
+        self.funcargnames = getfuncargnames(func, startindex=int(unittest))
         self.scope = scope
         self.scopenum = scopes.index(scope)
         self.active = False
+        self.unittest= unittest
         self._finalizer = []
 
-    def execute(self, kwargs):
+    def execute(self, posargs, kwargs):
         assert not self.active
         self.active = True
-        self.func(**kwargs)
+        self.func(*posargs, **kwargs)
 
     def addfinalizer(self, finalizer):
         assert self.active


diff -r bbd625a935b068c1e37f2273f79cdc4bdc1b4cee -r 93f393567640808a5c6166fe618adf38e37890d4 _pytest/unittest.py
--- a/_pytest/unittest.py
+++ b/_pytest/unittest.py
@@ -21,6 +21,8 @@
 
 class UnitTestCase(pytest.Class):
     def collect(self):
+        self.session.funcargmanager._parsefactories(self.obj, self.nodeid,
+                unittest=True)
         loader = py.std.unittest.TestLoader()
         module = self.getparent(pytest.Module).obj
         cls = self.obj
@@ -56,6 +58,8 @@
             pytest.skip(self._obj.skip)
         if hasattr(self._testcase, 'setup_method'):
             self._testcase.setup_method(self._obj)
+        if hasattr(self, "_request"):
+            self._request._callsetup()
 
     def teardown(self):
         if hasattr(self._testcase, 'teardown_method'):


diff -r bbd625a935b068c1e37f2273f79cdc4bdc1b4cee -r 93f393567640808a5c6166fe618adf38e37890d4 doc/en/unittest.txt
--- a/doc/en/unittest.txt
+++ b/doc/en/unittest.txt
@@ -24,8 +24,8 @@
 
     $ py.test test_unittest.py
     =========================== test session starts ============================
-    platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
-    plugins: xdist, bugzilla, cache, oejskit, pep8, cov
+    platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev12
+    plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
     collecting ... collected 1 items
     
     test_unittest.py F
@@ -47,3 +47,64 @@
 
 .. _`unittest.py style`: http://docs.python.org/library/unittest.html
 
+Moreover, you can use the new :ref:`@pytest.setup functions <@pytest.setup>` 
+functions and make use of pytest's unique :ref:`funcarg mechanism` in your
+test suite::
+
+    # content of test_unittest_funcargs.py
+    import pytest
+    import unittest
+
+    class MyTest(unittest.TestCase):
+        @pytest.setup()
+        def chdir(self, tmpdir):
+            tmpdir.chdir() # change to pytest-provided temporary directory
+            tmpdir.join("samplefile.ini").write("# testdata")
+
+        def test_method(self):
+            s = open("samplefile.ini").read() 
+            assert "testdata" in s
+
+Running this file should give us one passed test because the setup
+function took care to prepare a directory with some test data
+which the unittest-testcase method can now use::
+
+    $ py.test -q test_unittest_funcargs.py
+    collecting ... collected 1 items
+    .
+    1 passed in 0.28 seconds
+
+If you want to make a database attribute available on unittest.TestCases
+instances, based on a marker, you can do it using :ref:`pytest.mark`` and
+:ref:`setup functions`::
+
+    # content of test_unittest_marked_db.py
+    import pytest
+    import unittest
+
+    @pytest.factory()
+    def db():
+        class DummyDB:
+            x = 1
+        return DummyDB()
+
+    @pytest.setup()
+    def stick_db_to_self(request, db):
+        if hasattr(request.node.markers, "needsdb"):
+            request.instance.db = db
+
+    class MyTest(unittest.TestCase):
+        def test_method(self):
+            assert not hasattr(self, "db")
+
+        @pytest.mark.needsdb
+        def test_method2(self):
+            assert self.db.x == 1
+
+Running it passes both tests, one of which will see a ``db`` attribute
+because of the according ``needsdb`` marker::
+
+    $ py.test -q test_unittest_marked_db.py
+    collecting ... collected 2 items
+    ..
+    2 passed in 0.03 seconds


diff -r bbd625a935b068c1e37f2273f79cdc4bdc1b4cee -r 93f393567640808a5c6166fe618adf38e37890d4 setup.py
--- a/setup.py
+++ b/setup.py
@@ -24,7 +24,7 @@
         name='pytest',
         description='py.test: simple powerful testing with Python',
         long_description = long_description,
-        version='2.3.0.dev12',
+        version='2.3.0.dev13',
         url='http://pytest.org',
         license='MIT license',
         platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],


diff -r bbd625a935b068c1e37f2273f79cdc4bdc1b4cee -r 93f393567640808a5c6166fe618adf38e37890d4 testing/test_python.py
--- a/testing/test_python.py
+++ b/testing/test_python.py
@@ -1792,8 +1792,7 @@
         reprec.assertoutcome(passed=1)
 
 class TestSetupDiscovery:
-    def pytest_funcarg__testdir(self, request):
-        testdir = request.getfuncargvalue("testdir")
+    def pytest_funcarg__testdir(self, testdir):
         testdir.makeconftest("""
             import pytest
             @pytest.setup()
@@ -1832,6 +1831,21 @@
         reprec = testdir.inline_run("-s")
         reprec.assertoutcome(passed=1)
 
+    def test_setup_at_classlevel(self, testdir):
+        testdir.makepyfile("""
+            import pytest
+            class TestClass:
+                @pytest.setup()
+                def permethod(self, request):
+                    request.instance.funcname = request.function.__name__
+                def test_method1(self):
+                    assert self.funcname == "test_method1"
+                def test_method2(self):
+                    assert self.funcname == "test_method2"
+        """)
+        reprec = testdir.inline_run("-s")
+        reprec.assertoutcome(passed=2)
+
     def test_callables_nocode(self, testdir):
         """
         a imported mock.call would break setup/factory discovery


diff -r bbd625a935b068c1e37f2273f79cdc4bdc1b4cee -r 93f393567640808a5c6166fe618adf38e37890d4 testing/test_unittest.py
--- a/testing/test_unittest.py
+++ b/testing/test_unittest.py
@@ -480,3 +480,28 @@
     ])
 
 
+
+def test_unittest_setup_interaction(testdir):
+    testdir.makepyfile("""
+        import unittest
+        import pytest
+        class MyTestCase(unittest.TestCase):
+            @pytest.setup(scope="class")
+            def perclass(self, request):
+                request.cls.hello = "world"
+            @pytest.setup(scope="function")
+            def perfunction(self, request):
+                request.instance.funcname = request.function.__name__
+
+            def test_method1(self):
+                assert self.funcname == "test_method1"
+                assert self.hello == "world"
+
+            def test_method2(self):
+                assert self.funcname == "test_method2"
+
+            def test_classattr(self):
+                assert self.__class__.hello == "world"
+    """)
+    result = testdir.runpytest()
+    result.stdout.fnmatch_lines("*3 passed*")

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