Найти неиспользуемый код в приложении Rails - PullRequest
64 голосов
/ 16 марта 2012

Как мне узнать, что такое код и не запускается в производстве ?

Приложение хорошо протестировано, но есть много тестов, которые проверяют неиспользованный код. Следовательно, они получают покрытие при выполнении тестов ... Я хотел бы провести рефакторинг и очистить этот беспорядок, он продолжает тратить мое время. У меня много второстепенных заданий, поэтому я бы хотел, чтобы руководство по производственной деятельности помогло мне. Работая на heroku, я могу раскрутить динамометры, чтобы компенсировать любое влияние производительности от профилировщика.

Смежный вопрос Как найти неиспользуемые методы в приложении Ruby? бесполезно.

Бонус: метрика, показывающая, как часто выполняется строка кода. Не знаю, почему я этого хочу, но я хочу! :)

Ответы [ 11 ]

34 голосов
/ 20 марта 2012

При нормальных обстоятельствах подход будет использовать ваши тестовые данные для покрытия кода, но, как вы говорите, у вас есть части кода, которые тестируются, но не используются в производственном приложении, вы могли бы сделать что-то немного другое.

Для ясности: Не доверяйте автоматическим инструментам.Они будут показывать вам результаты только для тех вещей, которые вы активно тестируете, и ничего более.

С заявлением об ограничении ответственности я предлагаю вам использовать инструмент покрытия кода (например, rcov или simplecov для Ruby 1.9) в вашем производственном приложении и измерьте пути кода, которые фактически используются вашими пользователями.Хотя эти инструменты изначально были предназначены для измерения покрытия тестами, вы также можете использовать их для производственного покрытия

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

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

И последнее замечание: вы не найдете волшебный инструмент для полного анализа.Это потому, что ни один инструмент не может знать, используется ли определенный фрагмент кода фактическими пользователями или нет.Единственное, что могут сделать инструменты, - это создать (более или менее) статические графы достижимости, сообщающие вам, вызван ли ваш код каким-либо образом из определенной точки.С динамическим языком, таким как Ruby, даже этого довольно трудно достичь, поскольку статический анализ не дает особого понимания перед метапрограммированием или динамическими вызовами, которые интенсивно используются в контексте рельсов.Поэтому некоторые инструменты фактически запускают ваш код или пытаются получить представление о тестовом освещении.Но магических заклинаний определенно не существует.

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

21 голосов
/ 22 марта 2012

Возможно, вы можете попробовать использовать rails_best_practices для проверки неиспользуемых методов и класса.

Вот оно в github: https://github.com/railsbp/rails_best_practices.

Поместите 'gem "rails_best_practices" в ваш Gemfile и затем запустите rails_best_practices ., чтобы сгенерировать файл конфигурации

14 голосов
/ 04 марта 2014

Оформление обложки gem, он делает то, что вы ищете.

12 голосов
/ 04 января 2013

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

Dec 18 03:10:41 ip-xx-xx-xx-xx appname-p[7776]:   Processing by MyController#show as HTML

Поэтому я создал простой скрипт для анализа этой информации

zfgrep Processing production.log*.gz |awk '{print $8}' > ~/tmp/action

sort  ~/tmp/action | uniq -c |sort -g -r > ~/tmp/histogram

, который выдает результаты того, как часто к данному действию контроллера # обращались.

4394886 MyController#index
3237203 MyController#show
1644765 MyController#edit

Следующим шагом будет сравнение его со списком всех пар действий контроллера # в приложении (с использованием вывода маршрутизации rake или может выполнить тот же сценарий для комплекта тестирования)

4 голосов
/ 24 марта 2012

У вас уже есть идея пометить подозрительные методы как частные (что может повредить ваше приложение).

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

В вашем случае вы должны только регистрировать использование. Все, что не зарегистрировано после разумного периода времени, не используется.

4 голосов
/ 16 марта 2012

Я не очень знаком с Ruby и RoR, но я бы предложил несколько сумасшедших предположений:

  • add :after_filter метод, который регистрирует имя предыдущего вызванного метода (захватывает его из вызовастек) в файл
  • развернуть это в производство
  • подождать некоторое время
  • удалить все методы, которых нет в журнале.

ps вероятнорешение с Alt + F7 в NetBeans или RubyMine намного лучше:)

2 голосов
/ 27 марта 2012

Метапрограммирование

Объект # method_missing

переопределить Object#method_missing.Внутри, асинхронно, запишите вызывающие Class и method в хранилище данных.Затем вручную вызовите исходный метод с правильными аргументами на основе аргументов, переданных method_missing.

Дерево объектов

Затем сравните данные в хранилище данных с содержимым объекта приложения.tree.

отказ от ответственности: это, безусловно, потребует значительных производительности и учета ресурсов.Кроме того, потребуется некоторое время, чтобы заставить это работать, но теоретически это должно работать.Я оставлю это в качестве упражнения для оригинального плаката для его реализации.;)

1 голос
/ 23 марта 2012

Это не очень активный подход, но я часто использовал результаты, полученные из New Relic , чтобы узнать, было ли что-то, что я подозревал как неиспользуемое, было вызвано в производство в прошлом месяце или около того,Приложения, в которых я использовал это, были довольно маленькими, и прилично дорогими для больших приложений.

Я никогда не использовал это сам, но этот пост о лазерный камень , кажется, говорит о решении вашей точной проблемы.

1 голос
/ 22 марта 2012

Вы пытались создать набор тестов, используя что-то вроде sahi , тогда вы могли бы записывать все свои пользовательские журналы, используя это, и связывать эти тесты с rcov или чем-то подобным.

Вы должныубедитесь, что у вас есть все пользовательские журналы, но после этого вы можете посмотреть, что выплевывает rcov, и, по крайней мере, начать удалять то, что, очевидно, никогда не освещается.

0 голосов
/ 21 марта 2012

пометить подозрительные методы как частные.Если это не нарушает код, проверьте, используются ли методы внутри класса.тогда вы можете удалить вещи

...