【问题标题】:Why are tests failing in my Jenkins-Sonar plugin but not during the Jenkins-Maven run?为什么测试在我的 Jenkins-Sonar 插件中失败,但在 Jenkins-Maven 运行期间没有?
【发布时间】:2012-10-01 07:45:08
【问题描述】:

我在 CentOS 上运行 Jenkins 1.478,使用 Java 6、Maven 3.0.4、JUnit 4.8.1(Maven 项目中的依赖项)和 Sonar 3.2.1。我有我的 Jenkins Maven 2/3 作业设置以在完成后运行声纳(设置目标为“clean package -Pdev”)。该项目是一个包含 WAR 和 EAR 模块的多模块项目。但是,当插件的 Sonar 部分运行时,许多测试会因以下错误而死掉……

java.lang.NullPointerException
        at java.util.Properties$LineReader.readLine(Properties.java:418)
        at java.util.Properties.load0(Properties.java:337)
        at java.util.Properties.load(Properties.java:325)
        at org.parentco.myco.client.test.AbstractHibernateDaoTest.loadmyprojectProps(AbstractHibernateDaoTest.java:252)
        at org.parentco.myco.client.test.AbstractHibernateDaoTest.setupMockEjbContainer(AbstractHibernateDaoTest.java:235)
        at org.parentco.myco.client.test.AbstractHibernateDaoTest.setupBeforeClass(AbstractHibernateDaoTest.java:72)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:236)

异常来自此代码块的最后一行...

    final InputStream in = AbstractHibernateDaoTest.class.getClassLoader().getResourceAsStream("myproject.properties");
    final Properties props = new Properties();
    props.load(in);

测试在我工作的 Maven 部分运行完美。有问题的文件位于

./myclient-war/src/main/resources/myproject.properties

有人知道如何进一步解决此问题吗?我更愿意在 Sonar 中配置一些东西,而不是必须重组我的整个项目以适应 Sonar,但我愿意接受建议。

【问题讨论】:

  • 您是否尝试过从您的计算机运行声纳插件?您应该能够从命令行传递配置,而无需更改 pom。
  • 您可以在作业属性sonar.verbose=true 中为声纳指定调试标志。检查这是否提供了更多信息。

标签: maven junit jenkins classpath sonarqube


【解决方案1】:

试试“/myproject.properties”。

ClassLoader cl = AbstractHibernateDaoTest.class.getClassLoader();  
InputStream inTmp = cl.getResourceAsStream("myproject.properties");
if(itTmp==null){
    itTmp=cl.getResourceAsStream("/myproject.properties");
}
final InputStream in = inTmp;

【讨论】:

    【解决方案2】:

    这可能是由于 Sonar 为运行每个测试创建了一个单独的类加载器,尽管我不太确定。

    我相信所有失败的测试都遵循层次结构?

    YourTestClass 扩展了 AbstractHibernateDaoTest

    尝试使用YourTestClass 的直接测试类的类加载器加载文件,而不是总是尝试使用AbstractHibernateDaoTest 的类加载器加载它

    尝试将您的代码更改为,

    final InputStream in = this.getClass().getClassLoader()
                            .getResourceAsStream("myproject.properties");
    final Properties props = new Properties();
    props.load(in);
    

    这将确保您获得实际测试类的类对象而不是抽象类,以及直接类的类加载器而不是已经加载的类。

    更新: 一世 我觉得正在发生的事情是,无论您的代码中使用什么类加载器来加载资源,都无法看到 Maven 的类加载器。请注意,在您的情况下,Maven 尤其是 maven-surefire-plugin 负责设置正确的类路径。它将在类路径中添加src/main/resources 目录。

    【讨论】:

    • 我使用的是静态方法,所以不能使用“this”。我确实尝试过“ClassName.class.getResourceAsStream ...”,但这也没有用。
    • 我几乎可以肯定你可以重构你的代码来使用你测试类的类加载器。也许您可以将其作为参数传递给您的静态方法?
    • umm...他不是已经在使用测试类的类加载器了吗? “AbstractHibernateDaoTest”不是测试类吗?
    • 抽象这个名字让我很困扰。我不确定他的实际测试类(可能扩展抽象类)是否通过同一个类加载器加载?
    【解决方案3】:

    一种可能是this issue:

    基于 Spring 的 junit 测试与 Sonar 使用的 Cobertura 插件发生冲突。解决方法是使用 JaCoCo 或 EMMA 插件而不是 Cobertura。

    【讨论】:

      猜你喜欢
      • 2016-02-21
      • 1970-01-01
      • 2015-03-26
      • 1970-01-01
      • 2017-05-21
      • 2021-07-26
      • 1970-01-01
      • 2014-05-10
      • 2013-09-28
      相关资源
      最近更新 更多