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 випадково вибраних результатів із першої сторінки всі містили тести, які зробили кілька незалежних тверджень в одному і тому ж методі тестування. Всім було б корисно від тверджень, що не є фатальними.