Стратегия unit test и рефакторинг существующего приложения Grails

5 Mr. L [2011-01-20 14:09:00]


Какую стратегию вы бы порекомендовали unit test существующему приложению Grails?
Я только что прочитал книгу Бек Кента по TDD и хотел бы применить аналогичный подход к моему приложению. Моя цель состоит в unit test всей базе кода и в том, чтобы реорганизовать код и сделать его "чище". Под "чище" я подразумеваю, что хочу уменьшить дублирование, сделать мои контроллеры более тонкими, извлекая общую логику в сервисы и т.д.
Итак, с чего начать? Модели? Контроллеры?
Каков ваш "плохой" и "хороший" опыт, делающий подобное?

@Питеру. По моему мнению, мое приложение не слишком велико. он состоит из 12 + моделей, аналогичного количества контроллеров, нескольких сервисов и около 15 классов utils.
Одной из основных причин, по которой я хочу иметь полное покрытие unit test, является то, что во многих случаях система работает. Хотя это хорошо с точки зрения пользователя с точки зрения разработчика, такой код является кошмаром для изменения и поддержки.
Еще одна важная вещь, которую я хотел бы сделать небольшими и быстрыми регулярными выпусками (новые небольшие функции и/или улучшения), но без покрытия unit test это было бы практически невозможно.
Поэтому вопрос не в том: "Нужно ли это делать?", Но " Как я могу это сделать?"

unit-testing tdd grails


3 ответа


5 Решение Péter Török [2011-01-20 14:17:00]

В зависимости от размера приложения, но для любого нетривиального приложения для реальной жизни это огромная попытка удовлетворительно покрыть его модульными тестами. Поэтому вам нужно уделять первоочередное внимание вашим усилиям, сосредоточиться на наиболее важных/наиболее часто изменяемых/самых баггированных частях системы (обычно это перекрытие довольно много: наиболее важные части обычно чаще всего затрагивают, чтобы добавить новую функциональность или исправить ошибки).

Хорошим методом является запись модульных тестов более или менее в режиме TDD всякий раз, когда вам нужно коснуться любой части кода. Я написал "более или менее", потому что для устаревшего кода вам обычно нужно писать гораздо более сложные, более сложные модульные тесты, чем для разработки нового поля. Фактически, в некоторых случаях, возможно, даже не может быть продуктивным начать с модульных тестов, вместо этого лучше создать функциональные/системные тесты, чтобы покрывать большие зернистые функции с точки зрения пользователя.

Обратите внимание, что в зависимости от доступной документации и уровня знаний разработчика/пользователя о системе вы не всегда сможете определить "правильное" поведение для определенной функциональности, только ее текущее поведение. Даже в этом случае стоит покрыть его (единичными) тестами: они документируют фактическое поведение кода и обнаруживают в нем неожиданные изменения в будущем.

Как только у вас есть фактический фрагмент кода, который достаточно покрывается модульными тестами, это дает вам уверенность, необходимую для рефакторинга. Выполняйте некоторые (простые или сложные) рефакторинг, когда вы касаетесь кода. Однако не переусердствуйте. Если вам нужно изменить одну строку для исправления ошибок, может возникнуть перебор, чтобы начать реорганизацию целой иерархии наследования (даже если она действительно запутана). Делайте заметки о таких предстоящих задачах рефакторинга и пытайтесь планировать их позже.


3 hvgotcodes [2011-01-20 19:24:00]

Я вообще согласен с @Peter в том, что это нетривиальная вещь, и вам может мешать просто знать, что делаете, а не то, что они должны делать. Но это нормально, если не идеально, потому что тестирование - это как раз то, что касается ремонтопригодности (т.е. Знание, когда изменения нарушают вещи), поскольку речь идет о правильности. Поэтому поставьте тесты вокруг существующей функциональности, как сейчас, и если вам нужно исправить ошибку, вы можете изменить свой тест, чтобы зафиксировать исправление.

Если вы и ваша команда сосредоточены на добавлении новых функций, тогда выполните TDD сейчас, то есть протестируйте новую функциональность и добавьте тесты для существующих функций, которые вы модифицируете, как уже было предложено.

Если вы можете сосредоточиться на тестировании, то я бы тестировал в вертикальных слоях. Напишите несколько тестов для модели, затем ее сервисов, затем контроллеров (этот заказ - всего лишь предложение). Дело в том, что вы тестируете часть "Книги" своего приложения, проверяете всю функциональность книги, прежде чем двигаться дальше. Кроме того, вы можете расставить приоритеты по основным функциям приложения. Если "Книги" гораздо важнее, чем что-то еще, сначала проверьте "Книги" .


0 Navi [2011-01-20 14:21:00]

Лично мне было проще всего провести интеграционное тестирование Grails. Только для некоторых обычно используемых beans, я сделал модульное тестирование. Это не очень TDD, я признаю, но все же даю вам некоторую уверенность.