Изменить имена тестов, созданных генераторами носовых тестов

В Nose есть ошибка: имена тестов, созданные генераторами, не кэшируются, поэтому ошибка выглядит так, как будто она произошла в последнем тесте, а не в самом тесте, в котором она не удалась. Мне удалось обойти это, следуя решению в обсуждении отчета об ошибке, но это работает только для имен, отображаемых в стандартном выводе, а не в отчете XML (--with-xunit)

from functools import partial, update_wrapper
def testGenerator():
    for i in range(10):
        func = partial(test)
        # make decorator with_setup() work again
        update_wrapper(func, test)
        func.description = "nice test name %s" % i
        yield func

def test():
    pass

Выход носа, как и ожидалось, что-то вроде

nice test name 0 ... ok
nice test name 1 ... ok
nice test name 2 ... ok
...

Но имена тестов в XML — это просто «testGenerator».

...<testcase classname="example" name="testGenerator" time="0.000" />...

Как изменить это, чтобы имена персонализированных тестов отображались как в стандартном выводе, так и в формате XML?

Я использую носовые тесты версии 1.1.2 и Python 2.6.6.


person M.K.    schedule 25.06.2012    source источник
comment
Изменение «func.__name__» или «func.__doc__» также не работает.   -  person M.K.    schedule 25.06.2012
comment
Как насчет создания набора тестов?   -  person Apalala    schedule 26.06.2012
comment
@Apalala спасибо, кажется, это может решить эту проблему. Хотя я не могу найти никакой информации о том, как использовать это в носу и как это сочетается с обнаружением теста носа. Не могли бы вы привести пример, пожалуйста?   -  person M.K.    schedule 26.06.2012
comment
В прошлый раз, когда я пытался, нос не обнаруживал тесты, созданные во время выполнения.   -  person Apalala    schedule 12.11.2012


Ответы (4)


Вы можете изменить способ проверки имен Nose, добавив подключаемый модуль, реализующий описатьТест

from nose.plugins import Plugin
class CustomName(Plugin):
    "Change the printed description/name of the test."
    def describeTest(self, test):
         return "%s:%s" % (test.test.__module__, test.test.description)

Затем вам нужно будет установить этот подключаемый модуль и включить его в вызов Носа.

person dbn    schedule 15.12.2012

Вы можете добавить следующую строку.

testGenerator.__name__ = "nice test name %s" % i

Пример:

from functools import partial, update_wrapper
def testGenerator():
    for i in range(10):
        func = partial(test)
        # make decorator with_setup() work again
        update_wrapper(func, test)
        func.description = "nice test name %s" % i
        testGenerator.__name__ = "nice test name %s" % i
        yield func

def test():
    pass

Это приведет к именам, которые вы хотите.

<testsuite name="nosetests" tests="11" errors="0" failures="0" skip="0"><testcase classname="sample" name="nice test name 0" time="0.000" />
person Ananth Krishnan    schedule 16.05.2013
comment
Это почти работает, за исключением того, что все тесты получают одно и то же имя для меня (нос 1.2.1, питон 2.7.3) - person Rog; 17.05.2013

Как упоминает Анант, вы можете использовать это.

testGenerator.__name__

Вы также можете использовать это вместо

testGenerator.compat_func_name

Если у вашего тестового класса есть аргументы, я бы рекомендовал их каррировать, а также каррировать with_setup. Использование лямбды экономит на импорте, и я думаю, что это немного чище. Например,

from nose.tools import with_setup

def testGenerator():
    for i in range(10):
        func = with_setup(set_up, tear_down)(lambda: test(i))

        func.description = "nice test name %s" % i
        testGenerator.compat_func_name = func.description

        yield func

def test(i):
    pass

def set_up():
    pass

def tear_down():
    pass
person Dane White    schedule 14.02.2014
comment
Хороший призыв к каррингу - person Mad Physicist; 19.07.2016

Если вы используете нос и PyUnit от Eclipe:

import nose

class Test(object):
    CURRENT_TEST_NAME = None

    def test_generator(self):
        def the_test(*args,**kwargs):
            pass

        for i in range(10):
            # Set test name
            Test.CURRENT_TEST_NAME = "TestGenerated_%i"%i
            the_test.description = Test.CURRENT_TEST_NAME

            # Yield generated test
            yield the_test,i

    # Set the name of each test generated
    test_generator.address = lambda arg=None:(__file__, Test, Test.CURRENT_TEST_NAME)

что также приведет к тому, что имя будет хорошо отображаться в PyUnit.

Имена сгенерированных тестов

person frmdstryr    schedule 15.05.2014