Как вы справляетесь с большими изменениями?
По мере необходимости.
Иногда рефакторинги имеют большую поверхность, но тривиальны в деталях. Это можно сделать довольно большими шагами. Прилагать слишком много усилий, чтобы сломать их, будет напрасно.
Я бы сказал, что изменение библиотеки XML относится к этой категории. Вы помещаете XML и получаете некоторое представление. Пока ваше представление не меняется (от графика, представляющего состояние к потоку событий), переключать библиотеку легко.
В большинстве случаев рефакторинг не является тривиальным и должен быть разбит на части. Проблема в том, когда делать большие шаги, а когда - меньшие. Мое наблюдение состоит в том, что я довольно плохо оцениваю влияние изменений. Большинство программ достаточно сложны, так что вы можете подумать, что их изменения легко управляемы, но есть целый мелкий шрифт, который должен работать снова. Поэтому я начинаю с количества изменений. Но я готов откатить все, если это станет непредсказуемым. Я бы сказал, что это происходит в одном из десяти рефакторингов. Но это будет сложно. Вы должны отследить ту часть системы, которая не ведет себя так, как вы ожидаете. Проблема должна быть разделена на несколько небольших проблем. Я решаю одну проблему за раз и проверяю, когда это будет сделано. (Многократные итерации возврата и расщепления не редкость.)
Если вы измените синтаксический анализатор XML и представление в вашем коде, это, безусловно, должно быть как минимум два отдельных рефакторинга.
Пробное испытание
Вы тестируете протокол связи между объектами / слоями с фиктивными объектами.
Подход, основанный на моделировании, может служить моделью связи, подобной модели OSI . Когда уровень X получает вызов с параметром x, он вызывает уровень Z с параметрами a и b. Ваш тест определяет этот протокол связи.
Как бы полезна ни была фиктивная проверка, протестируйте с ними как можно меньше функциональных возможностей. Наилучшим вариантом являются тесты на основе состояния: установочное устройство, тестируемая система вызова, проверка состояния тестируемой системы и чисто функциональные (как в функциональном программировании) тесты: вызов с x возвращает a.
Постарайтесь спроектировать свою систему так, чтобы большая часть ее функций была слабо связана. Некоторые функции должны быть проверены с помощью фиктивных тестов (полностью отключенная система бесполезна).
Интеграционные тесты не являются опцией для тестирования вашей системы. Они должны использоваться только для тестирования аспектов системы, которые могут сломаться при интеграции нескольких устройств. Если вы попытаетесь протестировать свою систему с помощью интеграционных тестов, вы попадете в казино с перестановками.
Так что ваша стратегия тестирования GUI должна быть ясной. Части кода GUI, которые нельзя протестировать изолированно, следует тестировать с помощью фиктивных тестов (при нажатии этой кнопки сервис X вызывается с параметром y).
Базы данных немного мутят воду. Вы не можете смоделировать базу данных, если не собираетесь переопределить поведение каждой базы данных, которую хотели бы поддерживать. Но это не модульный тест, поскольку вы интегрируете внешнюю систему. Я примирился с этой концептуальной проблемой и думаю о DAO и базе данных как об одном неразделимом модуле, который можно протестировать с помощью подхода, основанного на состоянии. (К сожалению, этот аппарат ведет себя по-разному, когда у него есть свой оракульный день по сравнению с его днем MySQL. И он может сломаться посередине и сказать вам, что он не может разговаривать сам с собой.)