Тестовые утверждения для кортежей с поплавками - PullRequest
6 голосов
/ 11 июня 2010

У меня есть функция, которая возвращает кортеж, который, среди прочего, содержит значение с плавающей точкой. Обычно я использую assertAlmostEquals для сравнения, но это не работает с кортежами. Кроме того, кортеж содержит и другие типы данных. В настоящее время я утверждаю каждый элемент кортежа индивидуально, но это слишком много для списка таких кортежей. Есть ли хороший способ написать утверждения для таких случаев? Рассмотрим эту функцию:

def f(a):
    return [(1.0/x, x * 2) for x in a]

Теперь я хочу написать тест для него:

def testF(self):
    self.assertEqual(f(range(1,3)), [(1.0, 2), (0.5, 4)])

Это не удастся, потому что результат 1.0/2 не совсем 0.5. Кто-нибудь может порекомендовать хороший способ написания такого утверждения в удобочитаемой форме?

Редактировать : На самом деле 1.0/2 в точности 0.5, но вы меня поняли.

Ответы [ 3 ]

8 голосов
/ 29 июня 2010

Ну, как насчет того, чтобы улучшить свою функцию парой молний:

def testF(self):
    for tuple1, tuple2 in zip(f(range(1,3)), [(1.0, 2), (0.5, 4)]):
        for val1, val2 in zip(tuple1, tuple2):
            if type(val2) is float:
                self.assertAlmostEquals(val1, val2, 5)
            else:
                self.assertEquals(val1, val2)

Моя предпосылка здесь заключается в том, что лучше использовать несколько утверждений в цикле, чтобы получить точные значения, где он разрывается, по сравнению с использованием одного утверждения со всеми ().

пс. Если у вас есть другие числовые типы, для которых вы хотите использовать assertAlmostEquals, вы можете изменить, если выше, например, например. if type(val2) in [float, decimal.Decimal]:

3 голосов
/ 26 июня 2010

Я, вероятно, определю рекурсивную функцию.

from collections import Iterable;

def recursiveAssertAlmostEqual(testCase, first, second, *args, **kwargs):
   if isinstance(first, Iterable) and isinstance(second, Iterable):
      for a, b in zip(first, second):
         recursiveAssertAlmostEqual(testCase, a, b, *args, **kwargs)
   else:
      testCase.assertAlmostEqual(first, second, *args, **kwargs)

(Обратите внимание, что она будет утверждать (1, 2) и [1, 2] равны.)

2 голосов
/ 11 июня 2010

В прошлом я писал пользовательскую функцию, которая устанавливает валидность для сложного типа данных, а затем использовал assert( IsFooValid( foo ) ). Функция validity может просто возвращать true / false, но обычно лучше вызвать AssertionError с соответствующим сообщением.

...