I'm creating some tests for some laser-driver-functionality. For some lasers a piece of sub-functionality is supported, on others I should expect an error (and thus test that the error is raised). A sub-functionality is of-course (to keep it simple ;-) ) not 1 function, but multiple functions. So given the laser the test for a certain function should pass or fail.
The pass case is not a problem, but when it should fail and a function has multiple return-values the generic assert we created has the problem that it does not know how many return-values it should return to the test-function and thus our generic assert only returns 1 None-value in case of a laser that does not support the sub-functionality.
Because of this we have to check in the test for functions with multiple return-values if it should fail or pass and only than we can call our generic assert in the correct way.
But this is kind of ugly IMHO, since in that case we check if the sub-functionality is supported twice (where the goal of the generic assert was to do that in one place).
Is there a way to determine the number of return-values a function has upfront to calling the function?
The problem in pseudo-code:
The generic assert (plus the base-setup of the test):
import functionality_under_test as fut
class Functionality( unittest.TestCase ):
def shared_setup( self ):
Functionality._issupported = fut.subfunctionality.is_supported()
def _assert_sub_functionality( self, func, *args, **kwargs ):
retval = None # We don't know how many retvals there will be
if not self._issupported:
# Here is the place where it should determine how many
# return-values func really has and initialize retval as
# with the correct number of None's in a tuple / one None.
self.assert_raises( <expected error>, func, *args, **kwargs )
else:
# retval will be filled with either 1 value or a tuple by
# successful call.
retval = func( *args, **kwargs )
return retval
For functions with 1 return-value there is not a problem and thus we can do this:
def test_subfunc_func_1_retval( self ):
only_retval = self._assert_sub_functionality( subfunc_func_1_retval, <args>, <kwargs> )
<checks based on retval not being None>
But for testing functions with multiple return-values this does not work (raises an error since only 1 return is given where the test-function would expect multiple). So we made it like:
def test_subfunc_func_2_retvals( self ):
if not self._issupported:
# 'Fail' case, where an error is expected
retval1, retval2 = None
_ = self._assert_sub_functionality( subfunc_func_2_retvals, <args>, <kwargs> )
else:
# Pass-case, no error expected. This works fine.
retval1, retval2 = self._assert_sub_functionality( subfunc_func_2_retvals, <args>, <kwargs> )
<checks based on the retvals not being None>
The extra check on self._issupported here is kind of ugly IMHO.
Can this be done in a different way?
Can _assert_sub_functionality determine how many return-values a function has and return that many times None in case the subfunctionality is not supported?
TIA
Aucun commentaire:
Enregistrer un commentaire