Как проверить функции декоратора Python? - PullRequest
13 голосов
/ 02 ноября 2011

Я пытаюсь написать модульные тесты, чтобы убедиться в правильности написанных мной различных декораторов.Вот начало кода, который я пытаюсь написать:

import unittest

from memoizer import Memoizer
from strategies.mru import MRU


@Memoizer(strategy=MRU(maxsize=10))
def fib(x):
  if x < 2:
    return 1
  else:
    return fib(x-1) + fib(x-2)


class TestMemoizer(unittest.TestCase):

  def test_simple(self):
    self.assertEqual(fib(0), 1)
    self.assertEqual(fib(1), 1)
    self.assertEqual(fib(10), 89)


if __name__ == '__main__':
  unittest.main()

Хотя это работает прилично для стратегии MRU, описанной выше, я планирую написать дополнительные стратегии, и в этом случае мне нужно будет украситьс функцией FIB по-разному.(Вспомните, что, поскольку fib вызывает fib, установка fib2 = memoize (fib) не запоминает промежуточные значения, поэтому они не будут работать.) Как правильно проверить другие декораторы?

Ответы [ 2 ]

10 голосов
/ 02 ноября 2011

Взгляните на тесты в стандартной библиотеке для примеров: http://hg.python.org/cpython/file/3.2/Lib/test/test_functools.py#l553

Я обычно добавляю некоторые инструменты в упаковываемую функцию, чтобы я мог отслеживать вызовы.

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

2 голосов
/ 02 ноября 2011

Как насчет довольно сложного

def mkfib(strategy):
    @Memoizer(strategy=strategy)
    def fib(x):
      if x < 2:
        return 1
      else:
        return fib(x-1) + fib(x-2)
    return fib

Таким образом, вы могли бы сделать

fib1 = mkfib(MRU(maxsize=10))
self.assertEqual(fib1(0), 1)
self.assertEqual(fib1(1), 1)

fib2 = mkfib(MRU(maxsize=10)) # produces another cache
self.assertEqual(fib2(0), 1)
self.assertEqual(fib2(1), 1)
...