Ben Finney <[EMAIL PROTECTED]> wrote: > Summary: I'm looking for idioms in unit tests for factoring out > repetitive iteration over test data.
Thanks to those who've offered suggestions, especially those who suggested I look at generator functions. This leads to:: import unittest import bowling # Module to be tested class Test_Game(unittest.TestCase): """ Test case for the Game class """ def setUp(self): """ Set up test fixtures """ self.game_data = { 'none': dict(score=0, throws=[], frame=1), 'one': dict(score=5, throws=[5], frame=1), 'two': dict(score=9, throws=[5, 4], frame=2), 'three': dict(score=14, throws=[5, 4, 5], frame=2), 'strike': dict(score=26, throws=[10, 4, 5, 7], frame=3), } self.game_params = {} for key, dataset in self.game_data.items(): params = {} instance = bowling.Game() params['instance'] = instance params['dataset'] = dataset self.game_params[key] = params def iterate_params(test_params=None): """ Yield the test parameters """ if not test_params: test_params = self.game_params for key, params in test_params.items(): dataset = params['dataset'] instance = params['instance'] yield key, dataset, instance def test_score_throws(self): """ Game score should be calculated from throws """ for key, dataset, instance in self.iterate_params(): score = dataset['score'] for throw in dataset['throws']: instance.add_throw(throw) self.failUnlessEqual(score, instance.get_score()) def test_current_frame(self): """ Current frame should be as expected """ for key, dataset, instance in self.iterate_params(): frame = dataset['frame'] for throw in dataset['throws']: instance.add_throw(throw) self.failUnlessEqual(frame, instance.current_frame) That's much better. Each test is now clearly about looping through the datasets, but the infrastructure to do so is factored out. Adding a test case modelled on the existing cases just means adding a new entry to the game_data dictionary. Setting up a different kind of test -- e.g. for invalid game data -- just means setting up a new params dictionary and feeding that to the same generator function. I like it. Can it be improved? Are there readability problems that can be fixed? Is the test fixture setup too complex? Should the iterator become even more general, and be refactored out to a test framework for the project? -- \ "Those who can make you believe absurdities can make you commit | `\ atrocities." -- Voltaire | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list