Get name of current test in setup using nose

回眸只為那壹抹淺笑 提交于 2021-02-07 06:56:43

问题


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.


回答1:


Sounds like self._testMethodName or self.id() should work for you. These are property and method on unittest.TestCase class. E.g.:

from django.test import TestCase


class MyTestCase(TestCase):
    def setUp(self):
        print self._testMethodName
        print self.id()

    def test_one(self):
        self.assertIsNone(1)

    def test_two(self):
        self.assertIsNone(2)

prints:

...
AssertionError: 1 is not None
-------------------- >> begin captured stdout << ---------------------
test_one
path.MyTestCase.test_one

--------------------- >> end captured stdout << ----------------------
...
AssertionError: 2 is not None
-------------------- >> begin captured stdout << ---------------------
test_two
path.MyTestCase.test_two

--------------------- >> end captured stdout << ----------------------

Also see:

  • A way to output pyunit test name in setup()
  • How to get currently running testcase name from testsuite in unittest

Hope that helps.




回答2:


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.




回答3:


In the case you neither want to subclass unittest.TestCase or use a custom decorator (as explained in the other answers) you can get the information by digging through the call stack:

import inspect

def get_current_case():
    '''
    Get information about the currently running test case.

    Returns the fully qualified name of the current test function
    when called from within a test method, test function, setup or 
    teardown.

    Raises ``RuntimeError`` if the current test case could not be
    determined.

    Tested on Python 2.7 and 3.3 - 3.6 with nose 1.3.7.
    '''
    for frame_info in inspect.stack():
        if frame_info[1].endswith('unittest/case.py'):
            return frame_info[0].f_locals['self'].id()
    raise RuntimeError('Could not determine test case')


来源:https://stackoverflow.com/questions/16710061/get-name-of-current-test-in-setup-using-nose

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!