在Rails应用程序中查找未使用的代码

时间:2012-03-16 10:11:01

标签: ruby-on-rails ruby refactoring code-coverage

如何找到正在运行生产的代码?

该应用程序经过了充分测试,但有很多测试可以测试未使用的代码。因此,他们在运行测试时得到报道......我想重构和清理这个烂摊子,它不断浪费我的时间。 我有很多背景工作,这就是为什么我想要制作环境来指导我。在heroku运行我可以旋转dynos来补偿探查器对性能的影响。

相关问题How can I find unused methods in a Ruby app?没有帮助。

Bonus:用于显示运行代码行的频率的指标。不知道为什么我想要它,但我做到了! :)

11 个答案:

答案 0 :(得分:33)

在正常情况下,方法是使用您的测试数据进行代码覆盖,但正如您所说,您的部分代码经过测试但未在生产应用程序中使用,您可以做一些稍微不同的事情。

首先要明确:不要相信自动工具。他们只会向您显示您主动测试的内容的结果,仅此而已。

有了免责声明,我建议您在生产应用上使用代码覆盖率工具(如{1.9}}或rcov用于Ruby 1.9)并测量用户实际使用的代码路径。虽然这些工具最初是为测量测试覆盖率而设计的,但您也可以将它们用于生产范围

假设在测试时间范围内访问了所有相关的代码路径,您可以删除其余的代码路径。不幸的是,这种假设很可能不会完全成立。因此,在删除部件时,您仍然需要应用您对应用程序及其内部工作的了解。这在删除声明性部分(如模型引用)时更为重要,因为它们通常不会直接运行,而只用于配置系统的其他部分。

可以与上述方法结合使用的另一种方法是尝试将您的应用重构为可以打开和关闭的显着功能。然后,您可以关闭怀疑未使用的功能,并检查是否有人抱怨:)

最后一点:你找不到一个神奇的工具来进行全面的分析。那是因为没有工具可以知道实际用户是否使用了某段代码。工具可以做的唯一事情就是创建(或多或少)静态可达性图,告诉您代码是否以某种方式从某个点调用。使用像Ruby这样的动态语言,即使这很难实现,因为静态分析在面向元数据编程或在rails上下文中大量使用的动态调用时并没有带来太多洞察力。因此,有些工具实际运行您的代码或尝试从测试覆盖中获取洞察力。但绝对没有魔法咒语。

因此,考虑到rails应用程序的高内部(主要是隐藏)复杂性,您无需手动完成大部分分析。最好的建议可能是尝试模块化您的应用程序并关闭某些模块以测试它们是否未被使用。这可以通过适当的集成测试来支持。

答案 1 :(得分:21)

也许您可以尝试使用rails_best_practices来检查未使用的方法和类。

这里是github:https://github.com/railsbp/rails_best_practices

在您的Gemfile中放入'gem“rails_best_practices”'然后运行rails_best_practices .以生成配置文件

答案 2 :(得分:13)

结帐coverband宝石,它会完成您正在搜索的内容。

答案 3 :(得分:12)

我遇到了同样的问题,在探索了一些替代方案后,我意识到我已经开箱即用了所有可用的信息 - 日志文件。我们的日志格式如下

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 :(得分:4)

我对Ruby和RoR并不是很熟悉,但是我建议做一些疯狂的猜测:

  • 添加:after_filter方法,记录以前调用的方法的名称(从调用堆栈中获取)到文件
  • 将其部署到生产
  • 等一会儿
  • 删除所有不在日志中的方法。

P.S。可能在NetBeans或RubyMine中使用Alt + F7的解决方案要好得多:)

答案 5 :(得分:4)

您已经有了将可疑方法标记为私有的想法(可能会破坏您的应用程序)。

我过去做过的一个小变化:为所有可疑方法添加一小段代码来记录它。在我的例子中,它是一个用户弹出窗口“你称之为过时的功能 - 如果你真的需要请联系IT”。 一年之后,我们对实际使用的内容进行了很好的概述(这是一个商业应用程序,而且每年只需要一次功能)。

在您的情况下,您应该只记录用法。在合理的时间段之后未被记录的所有内容都未被使用。

答案 6 :(得分:2)

元编程

对象#method_missing的

覆盖Object#method_missing。在内部,将调用 Class 方法异步记录到数据存储中。然后根据传递给method_missing的参数,使用适当的参数手动调用原始方法。

对象树

然后将数据存储中的数据与应用程序对象树的内容进行比较。

免责声明:这肯定需要大量的性能和资源考虑。此外,它需要一些修补才能使它工作,但理论上它应该工作。我将把它留作原始海报的练习来实现它。 ;)

答案 7 :(得分:1)

您是否尝试使用类似sahi的内容创建测试套件,然后使用此功能记录所有用户日志,并将这些测试与rcov或类似内容联系起来。

你必须确保你拥有所有用户journies,但之后你可以看看rcov吐出来的东西,至少开始修剪那些显然从未被覆盖过的东西。

答案 8 :(得分:1)

这不是一种非常主动的方法,但我经常使用从New Relic收集的结果来查看我怀疑未使用的内容是否在过去一个月左右的任何时间被调用。我使用过的应用程序虽然很小,但对于大型应用程序来说却相当昂贵。

我自己从未使用过它,但关于this postlaser gem似乎在谈论解决您的确切问题。

答案 9 :(得分:0)

这不是完美的解决方案,但是在NetBeans中,您可以通过右键单击它们来找到方法的用法(或按Alt + F7)。
因此,如果方法未使用,您将看到它。

答案 10 :(得分:0)

将可疑方法标记为私有。如果这不会破坏代码,请检查方法是否在类中使用。然后你可以删除东西