2016-12-28 26 views
15

我目前正在测试使用jdk-9 + 149将Java 8应用程序迁移到Java 9/Jigsaw。我应该在将Java 8项目迁移到拼图时将单元测试放在哪里?

该项目已在标准的Maven目录结构进行布局,即具有src/main/javasrc/test/java

只要我添加module-info.javasrc/main/java,Maven的编译器插件无法抛出一个NullPointerException。这是因为它预计也会找到test目录的模块信息。所以,据我所见,选项有:

  • 将测试类保存在一个单独的模块中,这意味着它们只能访问主模块的导出包。
  • 将测试类与源代码一起移动到主模块中,这意味着主模块需要测试依赖关系。

很显然,这两个选项都不可取,所以我假设在Maven项目中测试Jigsaw模块是一种推荐的方法。非常,我找不到任何建议和例子。

编辑:并称,张贴问题时(对不起)我不认为相关的一些信息

+0

你在maven-compiler插件中指定了哪些源和目标作为配置?也请分享NPE的堆栈跟踪,以清除所面临的错误。 – nullpointer

+0

对不起,添加了一些更多的信息。但基本上,NPE只是导致我面临实际问题的症状,我将如何处理一般的测试。 – peterp

回答

9

对Java 9的Maven支持一般而言,特别是测试仍在de发展 - 许多事情都起作用,但其他事情却不行。没有看到NPE的堆栈跟踪,这当然是猜测,但我认为你ran into this error

更一般地说,单元测试如何与拼图一起工作的问题仍在讨论中 - 即使是on the Jigsaw mailing list

下面是我对此事的看法:

  1. 正如您注意,将测试到一个单独的模块将意味着只有公共类型在导出的包将可测试的,这肯定是不够的。可能有解决方法,但是这些要求或者编辑模块声明(源代码; module-info.java)或描述符(字节代码,module-info.class),或者添加大量的--add-exports命令行标志到javacjava命令编译和运行测试。这些都不是特别有趣,特别是如果你想用手工做。

  2. 将测试移动到源代码树中也是一个坏主意,原因很明显,其中最重要的原因是创建不带测试的JAR需要大量的小提琴。

  3. 另一种选择是使用--patch-module选项,该选项允许将class文件或JAR的内容添加到现有模块。这样testCompile步骤可以创建一个包含源文件的JAR文件。不幸的是,除非像上面描述的那样操纵模块声明/描述,否则如果没有为测试依赖关系添加java --add-reads的读取边缘,则无法执行生成的JAR。还是比上面好。

  4. 作为一种最后的手段,可以将生产JAR视为常规JAR而不是模块。最简单的方法可能是将它与测试JAR一起转储到类路径中。这种方式一切正常,如Java < 9.不幸的是,这将破坏使用功能的代码,假设它位于命名模块内(例如与反射API的某些类型的交互)。

就我个人而言,我认为3.是上述选项中最好的。它不需要改变项目布局,只需要对javacjava命令进行较小的添加。

+0

感谢您的详细解答,Nicolai。很高兴看到正在讨论的话题。我将使用选项3和1进行一些测试,但我不知道可以在命令行上添加导出。 – peterp

+2

很高兴我能帮到你。确保报告,在这里,有一篇文章,或邮件给拼图开发。此时基于实际实验的所有反馈都是有价值的。 – Nicolai

+0

我一定会:) btw:[罗伯特的评论](http://stackoverflow.com/questions/41366582/where-should-i-put-unit-tests-when-migrating-a-java-8-project-to -jigsaw#comment69959520_41370766)也表示选项3可能是要走的路线 – peterp

6

您必须至少使用maven-compiler-plugin 3.6.0来支持拼图。但是,自构建+148以来,类文件的二进制结构发生了变化,因此插件无法像以前那样提取模块名(模块名需要能够编译测试)。我正在为此做一个修复,但我可能依赖于新版本的ASM。

更新:maven-compiler-plugin-3.6.1已发布,因此对拼图的支持已恢复。

+0

谢谢,罗伯特。我没有把它看作是一个maven问题(当然NPE没有帮助) - 因为测试代码实际上没有模块化。所以即使代码编译并进入'unnamed'模块,从src模块测试的东西也不会按需要工作。但是阅读Nicolai的[anwer](http:// stackoverflow。com/a/41367802/1006823)我知道这仍在讨论中。 – peterp

+2

供参考:http://maven.apache.org/plugins/maven-compiler-plugin/xref/org/apache/maven/plugin/compiler/TestCompilerMojo.html#L259告诉你,maven-compiler-plugin正在使用解决方案3 @Nicolai已被验证为拼图团队的一些开发人员的正确方法 –

+0

我想我有一个误解 - 在我发现时间有更深的视线进入你的链接之后,我注意到这是实际的代码v3.6.0(我认为这是未来的实现尚未发布)。所以AFAICS(不知道Maven内部)看起来像我应该能够对我的模块化源(带有模块描述符)运行测试(无模块描述符),如果它不是那个NPE的话。如果是这样的话,应该可以在本地构建自己的编译器插件以使其可用于测试目的。 getModuleName的预期返回值是什么? – peterp

2

正如已经suggested here,使用Maven的编译器插件的更新版本:3.7.0将帮助您解决这个问题: -

<plugins> 
    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>3.7.0</version> 
     <configuration> 
      <source>9</source> 
      <target>9</target> 
      <compilerArgument>-Xlint:all</compilerArgument> 
     </configuration> 
    </plugin> 
</plugins> 

在哪里可以放置在同一目录下的单元测试它曾经在模块化之前。这里是基于JDK9和Maven3 +的sample project。该项目遵循如截图所示的目录结构: -

enter image description here

和POST这一切,你需要做的是使用下面的命令执行测试:

mvn test 

从的根目录项目找到测试将照常执行。