pythonunit-testingtestingnosenosetests

Get name of current test in setup using nose


I am currently writing some functional tests using nose. The library I am testing manipulates a directory structure.

To get reproducible results, I store a template of a test directory structure and create a copy of that before executing a test (I do that inside the tests setup function). This makes sure that I always have a well defined state at the beginning of the test.

Now I have two further requirements:

  1. If a test fails, I would like the directory structure it operated on to not be overwritten or deleted, so that I can analyze the problem.
  2. I would like to be able to run multiple tests in parallel.

Both these requirements could be solved by creating a new copy with a different name for each test that is executed. For this reason, I would like to get access to the name of the test that is currently executed in the setup function, so that I can name the copy appropriately. Is there any way to achieve this?

An illustrative code example:

def setup_func(test_name):
    print "Setup of " + test_name

def teardown_func(test_name):
    print "Teardown of " + test_name

@with_setup(setup_func, teardown_func)
def test_one():
    pass

@with_setup(setup_func, teardown_func)
def test_two():
    pass

Expected output:

Setup of test_one
Teardown of test_one
Setup of test_two
Teardown of test_two

Injecting the name as a parameter would be the nicest solution, but I am open to other suggestions as well.


Solution

  • I have a solution that works for test functions, using a custom decorator:

    def with_named_setup(setup=None, teardown=None):
        def wrap(f):
            return with_setup(
                lambda: setup(f.__name__) if (setup is not None) else None, 
                lambda: teardown(f.__name__) if (teardown is not None) else None)(f)
        return wrap
    
    @with_named_setup(setup_func, teardown_func)
    def test_one():
        pass
    
    @with_named_setup(setup_func, teardown_func)
    def test_two():
        pass
    

    This reuses the existing with_setup decorator, but binds the name of the decorated function to the setup and teardown functions passed as parameters.