Search code examples
pythonpython-multiprocessingnose

Python nose processes parameter and dynamically generated tests


I have the minimal working example below for dynamically generating test cases and running them using nose.

class RegressionTests(unittest.TestCase):
    """Our base class for dynamically created test cases."""

    def regression(self, input):
        """Method that runs the test."""

        self.assertEqual(1, 1)


def create(input):
    """Called by create_all below to create each test method."""

    def do_test(self):
        self.regression(input)
    return do_test


def create_all():
    """Create all of the unit test cases dynamically"""

    logging.info('Start creating all unit tests.')

    inputs = ['A', 'B', 'C']
    
    for input in inputs:

        testable_name = 'test_{0}'.format(input)
        testable = create(input)
        testable.__name__ = testable_name
        class_name = 'Test_{0}'.format(input)

        globals()[class_name] = type(class_name, (RegressionTests,), {testable_name: testable})
        logging.debug('Created test case %s with test method %s', class_name, testable_name)

    logging.info('Finished creating all unit tests.')


if __name__ == '__main__':

    # Create all the test cases dynamically
    create_all()

    # Execute the tests
    logging.info('Start running tests.')
    nose.runmodule(name='__main__')
    logging.info('Finished running tests.')

When I run the tests using python nose_mwe.py --nocapture --verbosity=2, they run fine and I get the output:

test_A (__main__.Test_A) ... ok
test_B (__main__.Test_B) ... ok
test_C (__main__.Test_C) ... ok

However, when I try to use the processes command line parameter to make the tests run in parallel, e.g. python nose_mwe.py --processes=3 --nocapture --verbosity=2, I get the following errors.

Failure: ValueError (No such test Test_A.test_A) ... ERROR
Failure: ValueError (No such test Test_B.test_B) ... ERROR
Failure: ValueError (No such test Test_C.test_C) ... ERROR

Is there something simple that I am missing here to allow the dynamically generated tests to run in parallel?


Solution

  • as far as I can tell you just need to make sure that create_all is run in every test process. just moving it out of the __main__ test works for me, so the end of the file would look like:

    # as above
    
    # Create all the test cases dynamically
    create_all()
    
    if __name__ == '__main__':
        # Execute the tests
        logging.info('Start running tests.')
        nose.runmodule(name='__main__')
        logging.info('Finished running tests.')