代码覆盖突出显示了未使用的方法-我该怎么办?


59

我的任务是增加现有Java项目的代码覆盖率。

我注意到,代码覆盖率工具(EclEmma)强调了一些从未在任何地方调用的方法。

我最初的反应不是为这些方法编写单元测试,而是向我的生产线经理/团队强调它们,并询问为什么要从那里开始使用这些功能。

最好的方法是什么?为他们编写单元测试,或者质疑为什么要在那里?


1
评论不作进一步讨论;此对话已转移至聊天
maple_shaft

Answers:


119
  1. 删除。
  2. 承诺。
  3. 忘记。

理由:

  1. 死代码是死的。根据其描述,它没有任何目的。它可能曾经有一个目的,但是那已经消失了,因此代码也应该消失了。
  2. 版本控制可确保(以我的经验)罕见的独特事件,即某人稍后出现来寻找该代码时,该事件可以被检索。
  3. 副作用是,您无需进行任何操作即可立即提高代码覆盖率(除非测试了无效代码,这种情况很少发生)。

注释中的警告:原始答案假定您已经彻底验证了代码毫无疑问已经死了。IDE容易出错,实际上有几种方法可以调用看似无效的代码。除非绝对确定,否则请专家来。


118
通常,我会同意这种方法,但是,如果您是项目和/或初级开发人员的新手,最好在删除之前询问您的导师/上级。根据项目的不同,某些方法可能看起来没有使用,但由外部代码调用/使用,不在您有权访问的项目代码中。它可能是自动生成的代码,所以除去日志历史记录噪音后,您的删除将不会产生任何效果。您的IDE可能无法在项目中找到基于反射的访问。等等pp。如果您不确定此类极端情况,请至少询问一次。
弗兰克·霍普金斯

11
尽管我同意这个答案的核心,但字面上的问题是“我应该质疑为什么它们在那里吗?” 。此答案可能会给人留下OP在删除之前不应询问其团队的印象。
布朗

58
我将首先添加一个步骤-检查git blame日志中是否有未使用的代码行。如果您可以找到编写它们的人,则可以询问它们的用途。如果这些线是新的,那么很有可能有人计划很快使用它们(在这种情况下,现在应该对它们进行单元测试)。
bdsl

10
正如评论或其他答案中所表达的那样,这个答案有很多问题,以至于我不敢相信这是最受投票和接受的答案。
user949300

11
@Emory成立新团队的最佳方法是通过不小心删除内容来破坏构建,因为您认为没有人需要它们。你是从第1天。当然这可能并不需要流行担保(因为每一个大的,旧的应用程序始终具有100%的代码覆盖率咳嗽),但是这是一个非常糟糕的投资回报率。
Voo

55

所有其他答案均基于这样的假设:所讨论的方法确实未使用。但是,问题并未指定该项目是自包含的还是某种类型的库。

如果所讨论的项目是一个库,则看似未使用的方法可以在项目外部使用,而删除它们会破坏其他项目。如果图书馆本身是出售给客户或公开提供的,则甚至不可能追踪这些方法的使用。

在这种情况下,有四种可能性:

  • 如果方法是私有的或包私有的,则可以安全地删除它们。
  • 如果这些方法是公开的,则即使没有实际使用也可以证明它们的存在是为了功能完整。他们应该进行测试。
  • 如果方法是公共的并且不需要,则删除它们将是一个重大更改,并且如果库遵循语义版本控制,则仅在新的主要版本中允许这样做。
  • 或者,也可以弃用公共方法,以后再将其删除。这样,API使用者就可以有一些时间从不赞成使用的功能过渡到在下一个主要版本中将其删除。

9
另外,如果它是一个库,那么功能是出于完整性的考虑
PlasmaHH

您能否详细说明如何进行测试?如果您不知道为什么使用该方法,则可能不知道该怎么做。
TKK

类似方法名称filter_name_existsReloadSettingsaddToSchema(3个任意开源项目随机挑选)应该会提供一些线索,以什么样的方法是应该做的事。javadoc注释可能更有用。我知道这不是一个适当的规范,但足以创建一些至少可以防止回归的测试。
Zoltan '18年

1
为此,不应将私有类或接口上的公共方法视为公共方法。同样,如果将公共班级嵌套在私人班级中,则它并不是真正的公共。
Emory

31

首先检查您的代码覆盖率工具是否正确。

我遇到过这样的情况,即它们没有采用通过对接口的引用来调用的方法,或者是否在某个地方动态加载了类。


谢谢,会的。在Eclipse上,我在代码库上搜索功能,但没有任何反应。如果您对如何进行更全面的搜索有任何其他建议,我将不胜感激。
卢卡斯T

3
是的,您应该检查其他可能将该类作为dll导入的项目
Ewan,

7
这个答案感觉不完整。“首先检查您的代码覆盖率工具是否正确。如果正确,则.... [插入其余的答案] “。具体来说,OP想知道如果代码覆盖率工具正确无误该怎么
乔恩·本特利

1
@jonbentley OP正在寻求工具报告的最佳方法。之所以选择“手动检查”,是因为从上下文中可以很明显地看出它是不正确的
-Ewan

15

由于Java是静态编译的,因此删除方法应该很安全。删除无效代码总是好的。很有可能存在一些疯狂的反射系统在运行时运行它们,因此请首先与其他开发人员联系,否则将其删除。


9
+1以便与人核对,这是遵循最不令人惊讶的原则。您不希望某人花太多时间寻找刚刚留下的一些提交方法。同样,在某些情况下,死代码可能是已经签入但尚未在任何地方连接的新内容(尽管在这种情况下,应使用注释将其很好地记录在案,并进行测试)。
Frax

4
好吧,除非代码使用反射来调用“未使用”的方法,但是在那种情况下,您会遇到更大的问题,我们期待在thefailywft.com上看到代码(如果有任何代码执行ClassName,请做一个快速测试,以检查该代码是否正确。)类)。
MTilsted '18年

2
它是静态编译的,但也有invokedynamic说明,因此,您知道……
corsiKa,

@MTilsted:有许多框架可以使用字符串来调用代码-我至少可以想到Spring和Hibernate。
jhominal

9

最好的方法是什么?为他们编写单元测试,或者质疑为什么要在那里?

删除代码是一件好事。

当您无法删除代码时,可以将其标记为@Deprecated,记录要删除该方法的目标主要版本。然后您可以“稍后”将其删除。同时,很明显,不应添加任何依赖它的新代码。

我不建议投资不推荐使用的方法-因此,没有新的单元测试只是为了达到覆盖率目标。

两者之间的区别主要在于方法是否是已发布接口的一部分。任意删除已发布界面的某些部分,对于依赖该界面的用户来说都是一个不愉快的惊喜。

我无法与EclEmma交谈,但是根据我的经验,您需要注意的一件事是反思。例如,如果您使用文本配置文件来选择要访问的类/方法,则使用/未使用的区别可能并不明显(我被那段时间累死了)。

如果您的项目是依赖关系图中的叶子,则不赞成使用的情况会减弱。如果您的项目是一个库,则弃用的理由更强。

如果您的公司使用mono-repo,则删除的风险要比multi-repo情况低。

l0b0所指出的,如果这些方法已在源代码控制中可用,则在删除后恢复它们是一种直接的练习。如果您真的担心需要这样做,请考虑一下如何组织提交,以便在需要时可以恢复已删除的更改。

如果不确定性足够高,您可以考虑注释掉代码,而不是删除它。在快乐的路径上(这是从不还原已删除的代码的),这是额外的工作,但确实使还原变得更容易。我的猜测是,您应该更喜欢直接删除,直到被这两次烧掉为止,这将使您对如何在这种情况下评估“不确定性”有一些见解。

问他们为什么在那里?

花在捕获知识上的时间并不一定浪费。众所周知,我需要执行两个步骤来执行删除操作:首先,通过添加并提交注释来解释我们对代码的了解,然后删除代码(和注释)。

您也可以使用类似于体系结构决策记录的方式来捕获源代码的知识。


9

代码覆盖率工具并非一无所知。仅仅因为你的工具,声称该方法不叫,这并不意味着它叫。存在反射,根据语言的不同,可能还有其他方法可以调用该方法。在C或C ++中,可能存在构造函数或方法名称的宏,并且该工具可能看不到调用。因此,第一步将是:对方法名称和相关名称进行文本搜索。问有经验的同事。您可能会发现它实际上已被使用。

如果不确定,请在每个“未使用”方法的开头放置一个assert()。也许它被调用了。或日志记录语句。

也许代码实际上是有价值的。同事已经工作了两个星期,可能明天要上班,这可能是新的密码。今天不调用它,因为它将在明天添加它的调用。

也许代码实际上是有价值的第2部分:代码可能正在执行一些非常昂贵的运行时测试,从而能够发现出错的地方。仅当实际出错时才打开代码。您可能正在删除有价值的调试工具。

有趣的是,最糟糕的建议是“删除,提交,忘记”。是最高评分。(代码审查?您不进行代码审查?如果您不进行代码审查,您在做什么编程?)


我非常反对“删除,提交,忘记”是最糟糕的建议。(我认为这是最好的。)您的方法也可以。我认为,最糟糕的建议是编写行使“死代码”但不声明的单元测试。代码覆盖率工具将被误认为使用它们。
Emory '18

3
“删除,提交,忘记”答案中没有任何内容表明不要进行代码审查。在提交代码之后(但在部署之前:-)),完全有可能(并且最好是恕我直言)查看代码。
sleske '18年

@sleske您如何查看不再存在的代码?这个答案也没有提到“评论”。
user949300 '18

@ user949300:是否需要检查代码更改是一个单独的问题,并且与代码是否被添加,更改或删除无关(添加代码比删除代码甚至更具灾难性,请参见例如Heartbleed漏洞)。另外,答案(现在)说“请专家”,这听起来与代码审查非常接近。
sleske '18

1
@ user949300:关于“如何查看不再存在的代码”-我希望这很明显:通过查看所选版本控制工具中的更改。您还如何评价更改(任何更改)?
sleske '18年

6

根据软件运行的环境,您可以记录是否曾经调用过该方法。如果在适当的时间内未调用该方法,则可以安全地删除该方法。

这是比仅删除方法更为谨慎的方法,如果在高度故障敏感的环境中运行,则可能很有用。

我们登录到专用的#unreachable-code备用频道,为每个要删除的候选人提供一个唯一的标识符,事实证明这是非常有效的。



则“合适的时间”会更长(尽管我确实喜欢“午夜后的男人”)
杰米·布尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.