From 98b2300266ea5f22eb6055aa880d09e60c88f6ea Mon Sep 17 00:00:00 2001 From: holger krekel Date: Wed, 30 Sep 2009 12:52:40 +0200 Subject: [PATCH] fix cached_setup to deal properly for test_functions with multiple args. closes #50 --HG-- branch : trunk --- doc/changelog.txt | 3 +++ doc/test/funcargs.txt | 6 +++--- py/test/funcargs.py | 16 +++++++++++----- testing/pytest/test_funcargs.py | 29 +++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/doc/changelog.txt b/doc/changelog.txt index 2e45a3f2b..ede46b4ff 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -1,6 +1,9 @@ Changes between 1.0.x and 'trunk' ===================================== +* fix issue50 - cached_setup now caches more to expectations + for test functions with multiple arguments. + * merge Jarko's fixes, issue #45 and #46 * add the ability to specify a path for py.lookup to search in diff --git a/doc/test/funcargs.txt b/doc/test/funcargs.txt index edb4032ef..0613a96f8 100644 --- a/doc/test/funcargs.txt +++ b/doc/test/funcargs.txt @@ -388,9 +388,9 @@ managing fixtures across test modules and test runs def cached_setup(setup, teardown=None, scope="module", extrakey=None): """ cache and return result of calling setup(). - The scope and the ``extrakey`` determine the cache key. - The scope also determines when teardown(result) - will be called. valid scopes are: + The requested argument name, the scope and the ``extrakey`` + determine the cache key. The scope also determines when + teardown(result) will be called. valid scopes are: scope == 'function': when the single test function run finishes. scope == 'module': when tests in a different module are run scope == 'session': when tests of the session have run. diff --git a/py/test/funcargs.py b/py/test/funcargs.py index a4684b551..4842aa40f 100644 --- a/py/test/funcargs.py +++ b/py/test/funcargs.py @@ -96,6 +96,7 @@ class FuncargRequest: self._plugins.append(self.instance) self._funcargs = self._pyfuncitem.funcargs.copy() self._provider = {} + self._currentarg = None def _fillfuncargs(self): argnames = getfuncargnames(self.function) @@ -109,16 +110,16 @@ class FuncargRequest: def cached_setup(self, setup, teardown=None, scope="module", extrakey=None): """ cache and return result of calling setup(). - The scope and the ``extrakey`` determine the cache key. - The scope also determines when teardown(result) - will be called. valid scopes are: + The requested argument name, the scope and the ``extrakey`` + determine the cache key. The scope also determines when + teardown(result) will be called. valid scopes are: scope == 'function': when the single test function run finishes. scope == 'module': when tests in a different module are run scope == 'session': when tests of the session have run. """ if not hasattr(self.config, '_setupcache'): self.config._setupcache = {} # XXX weakref? - cachekey = (self._getscopeitem(scope), extrakey) + cachekey = (self._currentarg, self._getscopeitem(scope), extrakey) cache = self.config._setupcache try: val = cache[cachekey] @@ -146,7 +147,12 @@ class FuncargRequest: if not self._provider[argname]: self._raiselookupfailed(argname) funcargprovider = self._provider[argname].pop() - self._funcargs[argname] = res = funcargprovider(request=self) + oldarg = self._currentarg + self._currentarg = argname + try: + self._funcargs[argname] = res = funcargprovider(request=self) + finally: + self._currentarg = oldarg return res def _getscopeitem(self, scope): diff --git a/testing/pytest/test_funcargs.py b/testing/pytest/test_funcargs.py index 23ee5a13a..689224fcc 100644 --- a/testing/pytest/test_funcargs.py +++ b/testing/pytest/test_funcargs.py @@ -258,6 +258,35 @@ class TestRequestCachedSetup: req1.config._setupstate._callfinalizers(item1) assert l == ["setup", "teardown", "setup", "teardown"] + def test_request_cached_setup_two_args(self, testdir): + testdir.makepyfile(""" + def pytest_funcarg__arg1(request): + return request.cached_setup(lambda: 42) + def pytest_funcarg__arg2(request): + return request.cached_setup(lambda: 17) + def test_two_different_setups(arg1, arg2): + assert arg1 != arg2 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*1 passed*" + ]) + + def test_request_cached_setup_getfuncargvalue(self, testdir): + testdir.makepyfile(""" + def pytest_funcarg__arg1(request): + arg1 = request.getfuncargvalue("arg2") + return request.cached_setup(lambda: arg1 + 1) + def pytest_funcarg__arg2(request): + return request.cached_setup(lambda: 10) + def test_two_funcarg(arg1): + assert arg1 == 11 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*1 passed*" + ]) + def test_request_cached_setup_functional(self, testdir): testdir.makepyfile(test_0=""" l = []