Я недавно завершил рефакторинг черного ящика. Я не могу проверить это, потому что не могу понять, как это проверить.
На высоком уровне у меня есть класс, инициализация которого включает в себя получение значений из некоторого класса B. Если класс B «пустой», он генерирует некоторые разумные значения по умолчанию. Я извлек эту часть в метод, который инициализирует класс B с теми же значениями по умолчанию.
Мне еще предстоит выяснить цель / контекст любого класса, или как они будут использоваться. Поэтому я не могу инициализировать объект из пустого класса B и проверить, что он имеет правильные значения / делает правильные вещи.
Моя лучшая идея - запустить оригинальный код, жестко закодировать результаты публичных методов в зависимости от инициализированных членов и протестировать новый код на предмет этого. Я не могу ясно сформулировать, почему я чувствую смутную неловкость от этой идеи.
Есть ли лучшая атака здесь?
источник
Ответы:
У тебя все хорошо!
Создание автоматических регрессионных тестов часто - лучшее, что вы можете сделать для рефакторизации компонента. Это может быть удивительно, но такие тесты часто могут быть написаны без полного понимания того, что делает компонент внутри, если вы понимаете «интерфейсы» ввода и вывода (в общем смысле этого слова). Мы делали это несколько раз в прошлом для полноценных унаследованных приложений, а не только для классов, и это часто помогало нам избегать взлома вещей, которые мы до конца не понимали.
Однако у вас должно быть достаточно тестовых данных и вы должны четко понимать, что делает программное обеспечение с точки зрения пользователя этого компонента, в противном случае вы рискуете пропустить важные тестовые примеры.
ИМХО, это хорошая идея - реализовать автоматизированные тесты до начала рефакторинга, а не после него, поэтому вы можете выполнять рефакторинг небольшими шагами и проверять каждый шаг. Сам рефакторинг должен сделать код более читабельным, поэтому он поможет вам лучше понять внутреннее устройство. Таким образом, порядок шагов в этом процессе
источник
Важными причинами написания модульных тестов является то, что они как-то документируют API компонента. Непонимание цели тестируемого кода - действительно проблема здесь. Покрытие кода является еще одной важной целью, которую трудно достичь, не зная, какие ветви выполнения существуют и как они запускаются.
Однако, если возможно сбросить состояние полностью (или создать новый объект тестирования каждый раз), можно написать тесты типа «мусор в мусор», которые просто подают в систему в основном случайный ввод и наблюдают за выводом.
Такие тесты трудно поддерживать, поскольку, когда они терпят неудачу, может быть сложно сказать, почему и насколько это серьезно. Охват может быть сомнительным. Однако они все еще намного лучше, чем ничего. Если такой тест не пройден, разработчик может пересмотреть последние изменения с большим вниманием и, надеюсь, найти ошибку там.
источник