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()