Tags: code, decided, dynamic, folder, folders, functionality, module, precisely, programming, purposes, python, re-use, unittest

dynamic unittest

On Programmer » Python

4,751 words with 2 Comments; publish: Wed, 02 Jan 2008 22:54:00 GMT; (20093.75, « »)

Hello,

I decided to re-use functionality of "unittest" module for my purposes.

More precisely, I have a list of folders. For each folder, code should

enter to the folder, execute a command and assert the output. It's

reasonable to use "unittest" here, but the problem is that "unittest"

doesn't support (== I haven't found how) dynamic creation of tests.

I thought it would be very easy, but due to lack of closures in Python

(more precisely, closures do exist, but they are counter-intuitive for

lisp programmers), I failed. Finally, I found a way using a global

variable. I exploit the fact that "unittest" uses "cmp" to arrange test

cases. Therefore, if we have an array of test names and sequential

number of running the common function, we know the name of the current

test. Here is a sample code:

--- <dynamic_unittest.py>

import sys, unittest

test_names = ['aaa', 'ddd', 'bbb']

test_names.sort()

test_index = 0

class DynamicTestCase(unittest.TestCase):

def one_test(self):

global test_index

test_name = test_names[test_index]

test_index = test_index + 1

# Ok for 'aaa' and 'bbb', failure for 'ddd'

assert test_name in ['aaa', 'bbb']

for test_name in test_names:

func_name = 'test_' + test_name

setattr(DynamicTestCase, func_name, DynamicTestCase.one_test)

suite = unittest.makeSuite(DynamicTestCase, 'test_')

if not unittest.TextTestRunner().run(suite).wasSuccessful ():

sys.exit(1)

--- </dynamic_unittest.py>

I think this code might help others, so I post it to the group.

Comments are welcome.

--

Oleg Parashchenko olpa.python.questionfor.info. http://xmlhack.ru/ XML news in Russian

http://uucode.com/blog/ Generative Programming, XML, TeX, Scheme

XSieve at XTech 2006: http://xtech06.usefulinc.com/schedule/detail/44

All Comments

Leave a comment...

  • 2 Comments
    • Oleg Paraschenko wrote:

      Quote:
      === Original Words ===

      Hello,

      >

      I decided to re-use functionality of "unittest" module for my purposes.

      More precisely, I have a list of folders. For each folder, code should

      enter to the folder, execute a command and assert the output. It's

      reasonable to use "unittest" here, but the problem is that "unittest"

      doesn't support (== I haven't found how) dynamic creation of tests.

      >

      I thought it would be very easy, but due to lack of closures in Python

      (more precisely, closures do exist, but they are counter-intuitive for

      lisp programmers), I failed. Finally, I found a way using a global

      variable. I exploit the fact that "unittest" uses "cmp" to arrange test

      cases. Therefore, if we have an array of test names and sequential

      number of running the common function, we know the name of the current

      test. Here is a sample code:

      >

      --- <dynamic_unittest.py>

      >

      import sys, unittest

      test_names = ['aaa', 'ddd', 'bbb']

      test_names.sort()

      test_index = 0

      >

      class DynamicTestCase(unittest.TestCase):

      def one_test(self):

      global test_index

      test_name = test_names[test_index]

      test_index = test_index + 1

      # Ok for 'aaa' and 'bbb', failure for 'ddd'

      assert test_name in ['aaa', 'bbb']

      >

      for test_name in test_names:

      func_name = 'test_' + test_name

      setattr(DynamicTestCase, func_name, DynamicTestCase.one_test)

      >

      suite = unittest.makeSuite(DynamicTestCase, 'test_')

      if not unittest.TextTestRunner().run(suite).wasSuccessful ():

      sys.exit(1)

      >

      --- </dynamic_unittest.py>

      >

      I think this code might help others, so I post it to the group.

      Comments are welcome.

      Here's what your code might look like with closures:

      import sys

      import unittest

      test_names = ['aaa', 'ddd', 'bbb']

      test_names.sort()

      class DynamicTestCase(unittest.TestCase):

      pass

      def make_test(test_name):

      def one_test(self):

      self.assert_(test_name in ['aaa', 'bbb'])

      return one_test

      for test_name in test_names:

      setattr(DynamicTestCase, 'test_' + test_name, make_test(test_name))

      if __name__ == "__main__":

      unittest.main()

      Peter

      #1; Wed, 02 Jan 2008 22:55:00 GMT
    • Hello Peter,

      thanks a lot. I've overlooked this simple way to create the right

      closure.

      --

      Oleg

      #2; Wed, 02 Jan 2008 22:56:00 GMT