Running generated nose tests
Question: Suppose I define a testFile.py python module with as follows.

    
    
    def test_evens():
        for i in range(0, 5):
            yield check_even, i, i*3
    
    def check_even(n, nn):
        assert n % 2 == 0 or nn % 2 == 0
    

When I let nose identify the tests in collect-only mode I get

    
    
    testFile.test_evens(0, 0) ... ok
    testFile.test_evens(1, 3) ... ok
    testFile.test_evens(2, 6) ... ok
    testFile.test_evens(3, 9) ... ok
    testFile.test_evens(4, 12) ... ok
    

I can run all tests using

> > nosetests -v testFile:test_evens

However, what if I only want to run testFile.test_evens(2, 6) (i.e., not all
the tests)? Is there any way to do this from the command line?


Answer: Nose cannot do this by default, to my knowledge. Here are some options:

**1\. Fake it from the command line**

Probably not what you're looking for, but I had to mention it. You could also
create a wrapper script to simplify this:

    
    
    python -c 'import testFile; testFile.check_even(2, 6)'
    

**2\. Create a custom nose test loader**

This is a little more involved, but you can create a custom test loader which
interprets the command-line arguments as specifying the generator to load,
pulls out tests and arguments from the generator, and returns a suite
containing the test(s) with the matching arguments.

Below is some example code which should give you enough to build on
(**runner.py**):

    
    
    import ast
    import nose
    
    class CustomLoader(nose.loader.TestLoader):
    
        def loadTestsFromName(self, name, module=None):
            # parse the command line arg
            parts = name.split('(', 1)
            mod_name, func_name = parts[0].split('.')
            args = ast.literal_eval('(' + parts[1])
    
            # resolve the module and function - you'll probably want to
            # replace this with nose's internal discovery methods.
            mod = __import__(mod_name)
            func = getattr(mod, func_name)
    
            # call the generator and gather all matching tests
            tests = []
            if nose.util.isgenerator(func):
                for test in func():
                    _func, _args = self.parseGeneratedTest(test)
                    if _args == args:
                        tests.append(nose.case.FunctionTestCase(_func, arg=_args))
            return self.suiteClass(tests)
    
    nose.main(testLoader=CustomLoader)
    

Executing it:

    
    
    % python runner.py 'testFile.test_evens(2, 6)' -v
    testFile.check_even(2, 6) ... ok
    
    % python runner.py 'testFile.test_evens(2, 6)' 'testFile.test_evens(4, 12)' -v
    testFile.check_even(2, 6) ... ok
    testFile.check_even(4, 12) ... ok
    
    % python runner.py 'testFile.test_evens(1, 3)' -v
    testFile.check_even(1, 3) ... FAIL
    

