EDIT: перейшов на кращий приклад і пояснив, чому це справжня проблема.
Я хотів би написати модульні тести на Python, які продовжують виконуватися, коли твердження не вдається, щоб я міг бачити кілька помилок в одному тесті. Наприклад:
class Car(object):
def __init__(self, make, model):
self.make = make
self.model = make # Copy and paste error: should be model.
self.has_seats = True
self.wheel_count = 3 # Typo: should be 4.
class CarTest(unittest.TestCase):
def test_init(self):
make = "Ford"
model = "Model T"
car = Car(make=make, model=model)
self.assertEqual(car.make, make)
self.assertEqual(car.model, model) # Failure!
self.assertTrue(car.has_seats)
self.assertEqual(car.wheel_count, 4) # Failure!
Тут метою тесту є переконання, що Car __init__правильно встановлює свої поля. Я міг би розбити його на чотири методи (і це часто є чудовою ідеєю), але в цьому випадку я вважаю більш зрозумілим зберегти його як єдиний метод, який перевіряє єдину концепцію ("об'єкт ініціалізовано правильно").
Якщо ми припустимо, що тут найкраще не розбивати метод, то у мене є нова проблема: я не бачу всіх помилок одночасно. Коли я виправляю modelпомилку і повторно запускаю тест, wheel_countпомилка з'являється. Це заощадило б час, щоб побачити обидві помилки під час першого запуску тесту.
Для порівняння, система модульного тестування C ++ від Google розмежовуєEXPECT_* твердження, що не є фатальними, та ASSERT_*твердження, пов’язані з фатальним :
Твердження подаються парами, які перевіряють одне і те ж, але по-різному впливають на поточну функцію. Версії ASSERT_ * генерують фатальні збої, коли вони виходять з ладу, і переривають поточну функцію. Версії EXPECT_ * генерують нефатальні помилки, які не скасовують поточну функцію. Зазвичай перевага надається EXPECT_ *, оскільки вони дозволяють повідомляти про кілька помилок у тесті. Однак слід використовувати ASSERT_ *, якщо немає сенсу продовжувати, коли дане твердження не вдається.
Чи є спосіб отримати EXPECT_*подібну поведінку в Python unittest? Якщо ні unittest, то чи існує інший модуль тестового модуля Python, який підтримує таку поведінку?
До речі, мені було цікаво, скільки реальних тестів може отримати користь від нефатальних тверджень, тому я переглянув деякі приклади коду (відредаговано 19.08.2014, щоб використовувати код пошуку замість Google Code Search, RIP). З 10 випадково вибраних результатів із першої сторінки всі містили тести, які зробили кілька незалежних тверджень в одному і тому ж методі тестування. Всім було б корисно від тверджень, що не є фатальними.