Изменение интерфейса требует обновления кода, который использует этот интерфейс. Тестовый код ничем не отличается от не тестового кода в этом отношении. Неизбежно, что тесты для этого интерфейса должны будут измениться.
Часто при изменении интерфейса вы обнаруживаете, что «слишком много» тестов ломаются, то есть тесты для в значительной степени не связанных функций оказываются зависимыми от этого интерфейса. Это может быть признаком того, что ваши тесты слишком широки и требуют рефакторинга. Есть много возможных способов, которыми это может произойти, но вот пример, который, как мы надеемся, показывает общую идею, а также конкретный случай.
Например, если изменился способ создания объекта Account, и это требует обновления всех или большинства ваших тестов для вашего класса Order, что-то не так. Большинство ваших модульных тестов Order, вероятно, не заботятся о том, как создается учетная запись, поэтому рефакторинговые тесты выглядят так:
def test_add_item_to_order(self):
acct = Account('Joe', 'Bloggs')
shipping_addr = Address('123 Elm St', 'etc' 'etc')
order = Order(acct, shipping_addr)
item = OrderItem('Purple Widget')
order.addItem(item)
self.assertEquals([item], order.items)
к этому:
def make_order(self):
acct = Account('Joe', 'Bloggs')
shipping_addr = Address('123 Elm St', 'etc' 'etc')
return Order(acct, shipping_addr)
def make_order_item(self):
return OrderItem('Purple Widget')
def test_add_item_to_order(self):
order = self.make_order()
item = self.make_order_item()
order.addItem(item)
self.assertEquals([item], order.items)
Этот конкретный шаблон является Методом создания .
Преимущество здесь состоит в том, что ваши методы тестирования для Order изолированы от того, как создаются Счета и Адреса; если эти интерфейсы меняются, вам нужно изменить только одно место, а не каждый отдельный тест, в котором используются учетные записи и адреса.
Вкратце: тесты тоже являются кодом, и, как и весь код, иногда они нуждаются в рефакторинге.