Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repetitive code in unittest testcase

I have a testcase that looks like this:

def MyTestCase(unittest.Testcase):
  def test_input01(self):
    input = read_from_disk('input01')
    output = run(input)
    validated_output = read_from_disk('output01')
    self.assertEquals(output, validated_output)
  def test_input02(self):
    input = read_from_disk('input02')
    # ...
  # and so on, for 30 inputs, from input01 to input30

Now, I understand that test code can be a bit repetitive, since simplicity is more important than conciseness. But this is becoming really error-prone, since when I decided to change the signature of some functions used here, I had to make the change in all 30 places.

I could refactor this into a loop over the known inputs, but I do want each input to remain a separate test, so I thought I should be making the test_inputxx methods.

What am I doing wrong?

like image 357
max Avatar asked Sep 11 '12 02:09

max


2 Answers

Write a helper function to remove the repetition from the test cases:

def MyTestCase(unittest.Testcase):
  def run_input_output(self, suffix):
    input = read_from_disk('input'+suffix)
    output = run(input)
    validated_output = read_from_disk('output'+suffix)
    self.assertEquals(output, validated_output)

  def test_input01(self): self.run_input_output('01')
  def test_input02(self): self.run_input_output('02')
  def test_input03(self): self.run_input_output('03')
like image 74
Ned Batchelder Avatar answered Nov 15 '22 17:11

Ned Batchelder


I like Ned Batchelder's solution. But for posterity, if you might often change the number of inputs, you could do something like:

def MyTestCase(unittest.Testcase):
    def __init__(self, *args, **kwargs):
        for i in range(1,31):
            def test(self, suffix=i):
                input = read_from_disk('input%02d' % suffix)
                output = run(input)
                validated_output = read_from_disk('output%02d' % suffix)
                self.assertEquals(output, validated_output)
            setattr(self, 'test_input%02d' % i) = test
        super(MyTestCase, self).__init__(*args, **kwargs)
like image 43
jcater Avatar answered Nov 15 '22 17:11

jcater