Python: использование doctests для классов
можно ли использовать концепцию doctest Python для классов, а не только для функций?
если да, то где я должен поместить doctests - в docstring класса или в docstring конструктора?
чтобы уточнить, я ищу что-то вроде:
class Test:
"""
>>> a=Test(5)
>>> a.multiply_by_2()
10
"""
def __init__(self, number):
self._number=number
def multiply_by_2(self):
return self._number*2
заранее спасибо,
Адам
4 ответов
вам не хватает кода для фактического запуска doctests в нижней части файла:
class Test:
<snip>
if __name__ == "__main__":
import doctest
doctest.testmod()
Что касается того, куда ставить тесты:
- если он тестирует класс в целом, я бы поместил их в docstring класса.
- если он тестирует конструктор, я бы поместил их в docstring конструктора.
- если он тестирует метод (как это, кажется, в этом случае), я бы фактически поместил его в docstring этого метода.
вместо создания экземпляра объекта в каждом методе вы можете использовать extraglobs
:
class Test:
def multiply_by_2(self):
"""
>>> t.multiply_by_2()
10
"""
return self._number*2
if __name__ == '__main__':
import doctest
doctest.testmod(extraglobs={'t': Test()})
модуль doctest ищет любые docstrings в файле и выполняет в нем любой встроенный код, поэтому да, можно использовать doctest для классов.
что касается того, лучше ли поместить doctests в docstring класса или конструктор, я думаю, это зависит от того, что именно вы документируете.
если docstring дает общий обзор класса и как его использовать, я думаю, что лучше поместить его в класс.
если строка docstring в частности, о том, как создавать экземпляры класса, тогда он должен идти в __init__
метод.
помните, что цель doctests в первую очередь состоит в том, чтобы иметь самоутверждающийся пример кода в документации, поэтому IMHO аспект документации должен иметь приоритет над аспектом тестирования.
Edit:
в вашем примере выше нет кода для выполнения doctest-running python test.py -v
выполнит основной код python, который просто определяет класс.
вам нужно добавить это в конец файла:
if __name__ == "__main__":
import doctest
doctest.testmod()
альтернативно, если вы используете Python 2.6 или более поздней версии запустите его с:
python -m doctest -v test.py
Я думаю, что документация doctest module не объясняет, как справиться с этим, и она должна лучше объяснять, что делать.
шаблон, который я понял для тестирования методов класса, которые не нуждаются в данных экземпляра, но могут нуждаться в доступе к данным класса, должен передать объект класса вместо экземпляра.
class Test:
"""
>>> Test.multiply_by_3(Test,2)
6
"""
def __init__(self, number):
self._number=number
_THREE = 3
def multiply_by_3(self, x):
return x*self._THREE
if __name__ == "__main__":
import doctest
doctest.testmod()