使用nose获取当前测试的名称

时间:2013-05-23 09:21:07

标签: python unit-testing testing nose nosetests

我目前正在使用nose编写一些功能测试。我正在测试的库操纵一个目录结构。

为了获得可重现的结果,我存储了测试目录结构的模板,并在执行测试之前创建了该模板的副本(我在测试setup函数中执行此操作)。这确保了我在测试开始时总是有一个定义良好的状态。

现在我还有两个要求:

  1. 如果测试失败,我希望它操作的目录结构被覆盖或删除,以便我可以分析问题。
  2. 我希望能够并行运行多个测试。
  3. 这两个要求都可以通过为每个执行的测试创建一个具有不同名称的新副本来解决。出于这个原因,我想访问当前在setup函数中执行的测试的名称,以便我可以适当地命名副本。有没有办法实现这个目标?

    一个说明性的代码示例:

    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
    

    预期产出:

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

    将名称作为参数注入将是最好的解决方案,但我也愿意接受其他建议。

3 个答案:

答案 0 :(得分:6)

self._testMethodNameself.id()之类的声音对您有用。这些是unittest.TestCase类的属性和方法。 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)

打印:

...
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 << ----------------------

另见:

希望有所帮助。

答案 1 :(得分:2)

我有一个适用于测试功能的解决方案,使用自定义装饰器:

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

这会重用现有的with_setup装饰器,但会将装饰函数的名称绑定到作为参数传递的setupteardown函数。

答案 2 :(得分:0)

如果您既不想继承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') 或使用自定义装饰器(如其他答案中所述),您可以通过挖掘调用堆栈来获取信息:

public MyForm()
    {
        InitializeComponent();

        timer = new System.Windows.Forms.Timer();
        timer.Interval = (1 * 1000); // 1 secs
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();

        readNetworkValues = true;
        networkReader = new Thread(() =>
        {
            Thread.CurrentThread.IsBackground = true;
            byte[] data = new byte[1024];
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 49003);
            UdpClient newsock = new UdpClient(ipep);
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

            while (readNetworkValues)
            {
                data = newsock.Receive(ref sender);
                dataSet = parseData(data); //Decrypts the data
            }
        newsock.Close();
        });
        networkReader.Start();
    }

    private void timer_Tick(object sender, EventArgs e)
    {
        if (dataSet != null)
        {
            lock (dataSet)
            {
                int currentRow = dataGrid.FirstDisplayedScrollingRowIndex;
                dataGrid.DataSource = dataSet;
                dataGrid.FirstDisplayedScrollingRowIndex = currentRow;
            }
        }
    }