how to make all assertions in a unit test execute

Terry Reedy tjreedy at udel.edu
Sat Oct 16 19:44:43 EDT 2010


On 10/16/2010 6:05 PM, Ben Finney wrote:
> jimgardener<jimgardener at gmail.com>  writes:
>
>> class FileNamesTest(unittest.TestCase):
>>       def setUp(self):
>>          self.dirname='/home/me/data'
>>
>>      def test_get_filenames(self):
>>          innerstr='tom'
>>          matching_names=get_filenames(self.dirname,innerstr)
>>          self.assertEquals(1,len(matching_names))
>>
>>          innerstr='myself'
>>          matching_names=get_filenames(self.dirname,innerstr)
>>          self.assertEquals(0,len(matching_names))
>>
>>          innerstr='jerry'
>>          matching_names=get_filenames(self.dirname,innerstr)
>>          self.assertEquals(3,len(matching_names))
>
> A side point unrelated to the question: your code will be easier to read
> if you follow PEP 8, specifically its recommendations regarding spaces
> around syntax (like ‘=’ and ‘,’).
>
>> when I run the unittest, if the test fails at the first assertion,the
>> other assertions are not executed at all.
>
> Yes, that's by design. Each function in a TestCase subclass is a test
> case; the function goes about testing *one thing*, and ends as soon as
> the test passes or fails.
>
>> How do I organize the test so that all assertions can run?
>
> Every test case should test exactly one true-or-false question. Name
> each test case after the assertion it's making, so the unittest output
> makes sense.
>
>      class get_filenames_TestCase(unittest.TestCase):
>           def setUp(self):
>              self.dirname = '/home/me/data'
>
>          def test_one_match_returns_one_item(self):
>              innerstr = 'tom'
>              matching_names = get_filenames(self.dirname, innerstr)
>              self.assertEquals(1, len(matching_names))
>
>          def test_no_match_returns_empty_sequence(self):
>              innerstr = 'myself'
>              matching_names = get_filenames(self.dirname, innerstr)
>              self.assertEquals(0, len(matching_names))
>
>          def test_three_matches_returns_three_items(self):
>              innerstr = 'jerry'
>              matching_names = get_filenames(self.dirname, innerstr)
>              self.assertEquals(3, len(matching_names))

The temptation to write unfactored duplicate code like this is a 
negative of unittest. The question is whether get_filenames gets the 
proper number of names. One way to do it with unittest is something like

def test_get_filenames_return_number(self):
   inputs = ('myself', 'tom', 'jerry')
   outputs= (      0,     1,       3)
   self.assertEquals(outputs,
    [len(get_filenames(self.dirname,f) for f in inputs])

Listing inputs and outputs first makes it easy to check pairs and revise 
if needed.

With hundreds or thousands of i/o pairs, something different would be 
needed.

-- 
Terry Jan Reedy





More information about the Python-list mailing list