Source code for taurus.test.base

#!/usr/bin/env python

#############################################################################
##
## This file is part of Taurus
## 
## http://taurus-scada.org
##
## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
## 
## Taurus is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
## 
## Taurus is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU Lesser General Public License for more details.
## 
## You should have received a copy of the GNU Lesser General Public License
## along with Taurus.  If not, see <http://www.gnu.org/licenses/>.
##
#############################################################################

"""This module provides basic utilities for usage in any test"""

__docformat__ = 'restructuredtext'

import functools


[docs]def insertTest(klass=None, helper_name=None, test_method_name=None, test_method_doc=None, tested_name=None, **helper_kwargs): """Decorator that inserts test methods from a helper method that accepts arguments. `insertTest` provides a very economic API for creating new tests for a given class based on a helper method. `insertTest` accepts the following arguments: - helper_name (str): the name of the helper method. `insertTest` will insert a test method which calls the helper with any the helper_kwargs (see below). - test_method_name (str): Optional. Name of the test method to be used. If None given, one will be generated from the tested class and helper names. - test_method_doc (str): Optional. The docstring for the inserted test method (this shows in the unit test output). If None given, a default one is generated which includes the input parameters and the helper name. - tested_name (str): Optional. The name of the class or feature being tested (if given, it will be used in default method names and docstrings). - \*\*helper_kwargs: All remaining keyword arguments are passed to the helper. This decorator can be considered a "base" decorator. It is often used to create other decorators in which the helper method is pre-set, as in the following example:: isPos = functools.partial(insertTest, helper_name='isPositive') @isPos(x=2) @isPos(x=10) class Foo(unittest.TestCase): def isPositive(self, x): self.assertTrue(x > 0) """ # Recipe to support decorating with and without arguments if klass is None: return functools.partial(insertTest, helper_name=helper_name, test_method_name=test_method_name, test_method_doc=test_method_doc, tested_name=tested_name, **helper_kwargs) # Check arguments and provide defaults if helper_name is None: raise ValueError('helper_name argument is not optional') if test_method_name is None: test_method_name = 'test_' if tested_name: test_method_name += '%s_' % tested_name test_method_name += helper_name # Append an index if necessary to avoid overwriting existing test methods name, i = test_method_name, 1 while (hasattr(klass, name)): i += 1 name = "%s_%i" % (test_method_name, i) test_method_name = name if test_method_doc is None: argsrep = ', '.join(['%s=%s' % (k, repr(v)) for k, v in helper_kwargs.items()]) if tested_name: test_method_doc = 'Testing %s with %s(%s)' % (tested_name, helper_name, argsrep) else: test_method_doc = 'Testing %s(%s)' % (helper_name, argsrep) # New test implementation def newTest(obj): helper = getattr(obj, helper_name) return helper(**helper_kwargs) # Add the custom docstring newTest.__doc__ = test_method_doc # Add the new test method with the new implementation setattr(klass, test_method_name, newTest) return klass
if __name__ == '__main__': # a demo of use of insertTest from taurus.external import unittest isPos = functools.partial(insertTest, helper_name='isPositive') isNeg = functools.partial(insertTest, helper_name='isPositive', expected=False) @isPos @isPos(x=2) @isPos(x=10) @isPos(x=5) @isNeg(x=-1) class FooTest(unittest.TestCase): def isPositive(self, x=1, expected=True): self.assertEqual(x > 0, expected) unittest.main(verbosity=2)