【问题标题】:How to exclude source code from coverage measurement in IntelliJ IDEA?如何从 IntelliJ IDEA 的覆盖率测量中排除源代码?
【发布时间】:2015-03-01 04:27:43
【问题描述】:

在一个项目中,我有一个 Utility 类,它看起来像这样:

public final class Util {
    private Util() {}
    public static String method1(InputStream in) {...}
    public static String method2(BufferedReader in) {...}
    public static String method3(File file) {...}
}

该类是一个实用程序类,因为它只包含static 方法。 因此它被声明为final,它的构造函数是private。 创建实例或派生子类根本没有任何意义。

我有一套用于测试项目的单元测试。 我正在使用 IntelliJ IDEA 来运行测试、测量和可视化代码覆盖率。 Utility class Util 的构造函数现在降低了覆盖率。 我希望看到 100% 的 100% 逻辑覆盖率。 像 Utility 类的私有构造函数这样的代码会降低覆盖率。

是否有可能(最好通过注释)将方法或构造函数标记为与代码覆盖率无关,以便将此类代码从覆盖率报告中排除,从而显示 100% 的覆盖率?

我知道从覆盖率报告中隐藏代码通常对您自己不利。我不介意报告是否会有“被忽略的项目”列表 - 实际上,这会很好,以检查是否有人忽略了不应忽略的内容。真正的重点在于覆盖没有意义的代码,例如 Utility 类的私有构造函数。

我试图找出annotations.jar 是否包含候选人。唯一看起来似乎可以做到的注释是TestOnly,但它不能实现这个目的。 我也在plugins/coverage/lib/*.jar 里偷看了一下,没找到应聘者,可能是我错过了?

更新 这个问题现在已经过时了。与此同时,IntelliJ IDEA 和 Jacoco 学会了如何忽略没有调用者的私有构造函数的覆盖。我不知道有任何其他 Java 中故意无法访问的代码示例会引发从覆盖率报告中排除的对话。

更新 2 这个问题可能再次与 Java 记录类的访问器相关。

【问题讨论】:

  • 您似乎对覆盖率报告的解释有误。未涵盖的代码可能会被解释为需要更多测试,或者可能被视为代码异味的迹象。在这种情况下,这是一种气味——你真的应该避免使用这样的实用程序类,它很可能是糟糕设计的产物,你应该尝试修复它而不是玩弄你的覆盖率报告。像这样的游戏报告是指标程序的最大问题之一,如果你在我的团队中,我们会讨论你认为你现在在做什么。
  • 对于那些不知道真正有问题的代码的人,我认为您使用的是非常强大和教条的语言。我同意实用程序类可能是一种气味,应该警告人们。但仅仅因为某事经常是坏的,并不意味着它总是坏的。无论如何,按照 Peter Lawrey 的建议,现在使用 enum。而且它非常有意义,因为这是一个具有预定义(空)实例集的类,并且现在覆盖率很高兴。 P.S.:如果在你的团队中,很高兴能有这样的谈话。宣扬清洁代码让我不再感到孤独。

标签: java intellij-idea code-coverage test-coverage


【解决方案1】:

我将enum 用于实用程序类,大多数覆盖工具都知道忽略它的方法。

public enum Util { ;

enumfinalprivate 默认构造函数。

【讨论】:

  • 我试过这个,它有效!我也尝试使用interface,但只有在没有private static 方法时才有效。它在当前情况下对我有帮助。我仍然希望有一个更通用的解决方案。
  • 您可以添加虚拟测试或嵌套类来调用私有方法来获得 100%
  • 你说得对,我可以,但我也想避免这种情况。
  • 您可以编写一个方法来调用具有注释的类的所有方法。这样你就可以标记方法被忽略。
  • 同时,JetBrains 甚至实现了“实用程序类应该是一个枚举”作为检查。他们真好。 :)
【解决方案2】:

这个问题目前已经超过一年了;但是,我认为我可以提供一种替代方法来忽略单元测试中的私有构造函数。尽管不太可能,但可以绕过 Java 中的私有构造函数。此外,将来可能会修改该类,有人可以添加构造函数等...进行单元测试来验证这一点可能会让人觉得多余,但它确实增加了另一个层次的意图清晰度。失败的单元测试肯定会引起我的注意,“我导致单元测试失败,我确定我知道我在这里要改变什么吗?”

事不宜迟,这里有一些示例代码。

这里我们有一个带有私有构造函数的类。

public final class ClassWithPrivateCtor
{
  private ClassWithPrivateCtor()
  {
    throw new AssertionError(String.format(
      "Illegal instantiation of class: %s.",
      this.getClass().getName()));
  }
}

这是在 Java 中调用私有构造函数的一种方式。

private static <T> void invokePrivateConstructor(final Class<T> type)
  throws Throwable
{
  final Constructor<T> constructor = type.getDeclaredConstructor();

  constructor.setAccessible(true);

  try
  {
    constructor.newInstance();
  }
  catch (InvocationTargetException ex)
  {
    throw ex.getTargetException();
  }
}

这就是我在单元测试中使用它的方式。

@Test(
  description = "Verify ClassWithPrivateCtor private constructor fails.",
  expectedExceptions = AssertionError.class)
public void classWithPrivateCtorTest()
  throws Throwable
{
  invokePrivateConstructor(ClassWithPrivateCtor.class);
}

我已经养成了以这种方式验证私有构造函数的习惯,只是为了清楚该类的初衷是实用程序类还是具有常量的类等...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 2020-09-07
    相关资源
    最近更新 更多