[py-svn] r7784 - in py/dist/py: . test

hpk at codespeak.net hpk at codespeak.net
Thu Dec 9 00:44:17 CET 2004


Author: hpk
Date: Thu Dec  9 00:44:17 2004
New Revision: 7784

Modified:
   py/dist/py/__init__.py
   py/dist/py/test/collect.py
   py/dist/py/test/drive.py
   py/dist/py/test/item.py
   py/dist/py/test/test_collect.py
Log:
implemented support for Generator (collection) functions and methods. 
plus a couple of tests. 

With this new hack you can yield parametrized tests in an easy 
("the best API is one that doesn't exist") way: 

    def somefunc(x, y): 
        assert x * y == 42

    def test_generator(): 
        yield somefunc, 6, 7 
        yield somefunc, 7, 6 

There are still some semantical issues to be sorted 
out with respect to setup/teardown semantics.  Also
reporting for such generated tests has not been considered 
so far (and may be broken but there are not tests for that 
and i can't be bothered right now). 



Modified: py/dist/py/__init__.py
==============================================================================
--- py/dist/py/__init__.py	(original)
+++ py/dist/py/__init__.py	Thu Dec  9 00:44:17 2004
@@ -17,6 +17,7 @@
     'test.collect.PyCollector':'./test/collect.PyCollector',
     'test.collect.Error':      './test/collect.Error',
     'test.Item':               './test/item.Item', 
+    'test.GeneratorItem':      './test/item.GeneratorItem', 
     'test.Driver':       './test/drive.Driver', 
     'test.Option':       './test/tool/optparse.Option', 
     'test.TextReporter': './test/report/text/reporter.TextReporter',

Modified: py/dist/py/test/collect.py
==============================================================================
--- py/dist/py/test/collect.py	(original)
+++ py/dist/py/test/collect.py	Thu Dec  9 00:44:17 2004
@@ -23,6 +23,7 @@
         Collector instances during iteration.  
     """
     Item = test.Item 
+    GeneratorItem = test.GeneratorItem 
     Error = Error
 
     def iterunits(self):
@@ -133,8 +134,11 @@
 
     def collect_function(self, extpy):
         if extpy.check(func=1, basestarts='test_'):
-            #if self.extpy.samefile(extpy): not nfs/different mountpoint safe 
-            yield self.Item(extpy)
+            if extpy.check(genfunc=1): 
+                yield Generator(extpy) 
+            else: 
+                #if self.extpy.samefile(extpy): not nfs/different mountpoint safe ? 
+                yield self.Item(extpy)
 
     def collect_class(self, extpy):
         #print "checking %r (extpy: %r)" % (extpy.resolve(), extpy)
@@ -149,6 +153,31 @@
         # we don't check for "samemodule"-ness of test 
         # methods like in the Module Collector
         if extpy.check(basestarts='test_', func=1):
-            func = extpy.resolve()
-            yield getattr(func.im_class, 'Item', self.Item)(extpy)
+            if extpy.check(genfunc=1): 
+                yield Generator(extpy) 
+            else: 
+                func = extpy.resolve()
+                yield getattr(func.im_class, 'Item', self.Item)(extpy)
+
+class Generator(PyCollector): 
+    def dispatch(self, obj): 
+        if isinstance(obj, (tuple, list)): 
+            call = obj[0]
+            args = obj[1:]
+        else:
+            call = obj 
+            args = ()
+        #if hasattr(call, 'gi_running'): 
+        #    return ... Generator(py.path.obj(call), *args) 
+        return self.GeneratorItem(self.extpy, call, *args) 
 
+    def __iter__(self):
+        try:
+            sm = self.GeneratorItem.setupmanager 
+            sm.setup_path(self.extpy) 
+            gen, teardown = sm.setup_method(self.extpy) 
+            assert not teardown, "%r not processoable in Generator-Collector (XXX)" 
+            for call in gen(): 
+                yield self.dispatch(call) 
+        except:
+            yield self._except()

Modified: py/dist/py/test/drive.py
==============================================================================
--- py/dist/py/test/drive.py	(original)
+++ py/dist/py/test/drive.py	Thu Dec  9 00:44:17 2004
@@ -30,7 +30,7 @@
 
     def teardown(self):
         """ teardown any resources we know about. """ 
-        # XXX 
+        # XXX a cleaner way to teardown setupmanagers? 
         py.test.Item.setupmanager.teardown() 
 
     def run(self, collectors):

Modified: py/dist/py/test/item.py
==============================================================================
--- py/dist/py/test/item.py	(original)
+++ py/dist/py/test/item.py	Thu Dec  9 00:44:17 2004
@@ -92,6 +92,23 @@
     class ExceptionFailure(Failed): pass
     class Skipped(Outcome): pass 
 
+class GeneratorItem(Item): 
+    def __init__(self, extpy, call, *args): 
+        super(GeneratorItem, self).__init__(extpy, *args) 
+        self.call = call 
+        assert callable(call), "generated test %r is not callable" % (call,) 
+  
+    def execute(self, driver): 
+        self.setupmanager.setup_path(self.extpy) 
+        # XXX target is superflous here 
+        target, teardown = self.setupmanager.setup_method(self.extpy) 
+        try: 
+            print "calling %r%r" %(self.call, self.args) 
+            self.call(*self.args) 
+        finally: 
+            if teardown: 
+                teardown(target) 
+
 #
 # triggering specific outcomes from executing Items 
 #
@@ -102,3 +119,4 @@
 def fail(msg="unknown failure"): 
     """ fail with the given Message. """
     raise py.test.Item.Failed(msg=msg, tbindex=-2) 
+

Modified: py/dist/py/test/test_collect.py
==============================================================================
--- py/dist/py/test/test_collect.py	(original)
+++ py/dist/py/test/test_collect.py	Thu Dec  9 00:44:17 2004
@@ -77,3 +77,37 @@
         self.reslist.append(3)
     def test_4(self):
         assert self.reslist == [1,2,3]
+
+#
+# some tests related to "generating tests"
+#
+l2=[]
+
+def func1(): 
+    print "in func1"
+    l2.append(1) 
+
+def func2(i): 
+    print "in func2 with param %d" % i
+    l2.append(i) 
+
+def test_generator(): 
+    yield func1
+    yield func2, 2 
+    yield func2, 3 
+
+def test_stateful_previous(): 
+    x = l2
+    assert x == [1,2,3]
+
+class TestGeneratorMethod: 
+    l3 = []
+    def func1(self, i): 
+        self.l3.append(i) 
+
+    def test_generator(self): 
+        yield self.func1, 4 
+        yield self.func1, 5
+
+    def test_previous_generator_worked(self): 
+        assert self.l3 == [4,5]



More information about the pytest-commit mailing list