Как изменить строку документации класса TestCase в Python? - PullRequest
2 голосов
/ 01 мая 2011

В Python 2.5 (фактически, Jython) для класса TestTase UnitTest нет метода SetUpClass, и __init__ не совсем приемлемо (без ссылки на self).Когда я пытаюсь изменить строку документации внутри TestCase:

import os
fileName = os.path.split(__file__)[1]
testCaseName = os.path.splitext(fileName)[0]
setattr(__name__, '__doc__', testCaseName)

Я получаю:

setattr(__name__, '__doc__', testCaseName)
TypeError: readonly attribute

Я пытался изменить строку документации, создав ее экземпляр в объекте (где self.__doc__доступно для записи).

ОБНОВЛЕНО: но я хочу избежать дополнительного кодирования в подклассе (то есть наследовать функцию суперкласса для установки строки документа подкласса), например:

Файл DynamicTestCase.py содержит:

class DynamicTestCase(unittest.TestCase):
    def setDocstring(self, testCaseDocstring=None):
        if not testCaseDocstring:
            fileName = os.path.split(__file__)[1]
            testCaseDocstring = os.path.splitext(fileName)[0]
        setattr(self, '__doc__', testCaseDocstring)

Файл MyTestCase.py включает в себя:

class MyTestCase(DynamicTestCase):
    def test_print_docstring(self):
        self.setDocstring()
        print 'MyTestCase Docstring = ', self.__doc__

НоТем не менее, результат выполнения юнит-теста:

MyTestCase Docstring = DynamicTestCase

Когда я ожидал MyTestCase Docstring = MyTestCase

Ответы [ 2 ]

1 голос
/ 02 мая 2011

Обновлено - __file__ - это имя пути, из которого был загружен текущий модуль , поэтому, естественно, использование __file__ в DynamicTestCase.py приведет к пути DynamicTestCase.py,Однако вы можете просто передать путь в setDocstring() из подклассов, например:

DynamicTestCase.py :

class DynamicTestCase(unittest.TestCase):
    def setDocstring(self, docstring=None):
        if docstring is None:
            docstring = __file__
        if os.path.exists(docstring):
            name = os.path.split(docstring)[1]
            docstring = os.path.splitext(name)[0]
        setattr(self, '__doc__', docstring)

MyTestCase.py :

class MyTestCase(DynamicTestCase):
    def __init__(self, *args, **kwargs):
        DynamicTestCase.__init__(self, *args, **kwargs)
        self.setDocstring(__file__)

    def test_print_docstring(self):
        print 'MyTestCase Docstring = ', self.__doc__

    def test_new_docstring(self):
        self.setDocstring('hello')
        print 'MyTestCase Docstring = ', self.__doc__

Вывод:

MyTestCase Docstring =  MyTestCase
MyTestCase Docstring =  hello

Остальная часть ответа

В вашем исходном коде выше __name__ являетсяСтрока, а не класс.Jython справедливо отвергает изменение атрибута __doc__ для типа str.

Не могли бы вы немного рассказать о , почему вы хотите изменить строку документации TestCase?Например, вы можете создать подкласс TestCase и указать собственную строку документации:

class MyTestCase(unittest.TestCase):
    "Docstring of MyTestCase"

Не уверен, что вы уже пробовали это сделать, но в TestCase пакета unittest2 есть методы класса setUpClass, tearDownClass.Это бэкпорт улучшений Python 2.7 для работы с Python 2.6 и более ранними версиями.

Jython позволяет устанавливать __doc__ классов нового стиля, но CPython этого не делает.По этой причине вы можете захотеть найти другой способ достичь своей цели, если вы хотите, чтобы ваш код был переносимым:

Jython 2.2.1 on java1.6.0_24
>>> unittest.TestCase.__doc__ = 'foo bar'
>>> unittest.TestCase.__doc__
'foo bar'

Python 2.6.6 (r266:84292, Feb 12 2011, 01:07:21)
>>> unittest.TestCase.__doc__ = 'foo bar'
AttributeError: attribute '__doc__' of 'type' objects is not writable
0 голосов
/ 03 мая 2011

Вы захватываете имя файла файла DynamicTestCase, а не файла, который вызывает функцию.Для того, чтобы получить это, вы должны войти в кадр стека:

  import inspect

  class DynamicTestCase(unittest.TestCase):
    def setDocstring(self, testCaseDocstring=None):
        if not testCaseDocstring:
            fileName = 'unknown.py'

            # Go up one stack frame and grab the file name
            stack = inspect.stack()
            try:
                frame = stack[1][0]
                fileName = frame.f_code.co_filename        
            finally:
                del stack

            testCaseDocstring = os.path.splitext(fileName)[0]
...