使用Maven分离测试和核心项目

时间:2014-04-18 12:54:15

标签: java maven junit pom.xml

我已经找到了这篇文章:Separating tests from src with Maven Project?

  

我刚刚开始研究Java项目(我通常使用.net),并且是第一个>之一。令我感到奇怪的是,在Maven项目中有一个/ src和一个/ test   显然源代码和测试应该去的目录。

     

在.net中我更喜欢在单独的程序集/项目中进行测试,例如我   会有:

     

MyProject的   MyProject.Tests   这样我就不必使用任何测试来扩展我部署的代码,这使得它更容易   在真正的隔离中测试我的代码,在很多情况下,我没有费心去编写测试   项目,我只需要解决方案广泛的单元/集成/验收测试,即   MySolution.UnitTests,MySolution.IntegrationTests。

     

然而在Java中,它似乎只是捆绑在一起,我宁愿把它分开,>但是,当你想要以不同的方式做事时,我听说Maven是一个残酷的情妇   默认结构。

     

所以重新回到这个帖子,我的主要问题是:

     

有没有办法将测试与项目分开 [如何?]

虽然这个问题确切地描述了我试图实现的目标,但是线程还没有提供解决方法来解决这个问题。

我想知道是否有办法让JUnit进行(单元)测试的单独项目。我想在“核心”项目中使用实际的源代码,在单独的“测试”项目中使用相应的测试,而不是使用src / main和src / test路径的单个项目。 但是,我不知道如何配置(父)pom.xml文件来实现它。

到目前为止,我定义了一个父pom,它将两个项目声明为模块。另外,对于这两个项目中的每一个,我都有一个单独的pom文件来声明所需的依赖项等。当然,测试项目的pom文件将核心项目定义为依赖项。

我想我必须配置核心项目的pom文件,告诉测试插件查看其他项目的测试。但是如何配置这种行为?

2 个答案:

答案 0 :(得分:3)

如果您遵循Maven约定(同时拥有src和测试文件夹),您将获得更轻松的时间。您的测试将不会与您的编译源一起部署,因此我不会担心膨胀。 Maven将编译jar和测试jar文件(假设你正在使用jar)。如果你真的想要单独的src / test模块,那么是的,采用共同父模式的多模块方法就是你要走的路。测试模块将依赖于源模块,但不是相反。真的,这只是重塑了Maven已经为你做的事情。

从长远来看,我觉得使用传统方法你会更开心,因为事情会变得更顺畅。

答案 1 :(得分:0)

不要理会那些试图说服您必须按照既定方式之一进行操作的反对者,否则您会遇到麻烦。这是货物崇拜工程,它反映了普通企业员工的懦弱,他们宁愿死也不愿尝试不同的东西或跳出框框思考片刻。

拥有一个包含大量测试的大型多模块 maven 项目是完全可行的,其中没有一个模块同时包含生产和测试子文件夹,而是每个模块都是生产或测试。这是他们在 DotNet 世界中唯一的做法,我从未听到有人抱怨。

在某些情况下,您绝对必须以这种方式拆分模块,因此 maven 只能支持这一点。当依赖关系使得模块 A 的测试依赖于模块 B 而模块 B 又依赖于模型 A 的生产代码时,就会出现这种情况。 如果模块 A 的测试和生产代码都在同一个实际模块中,则会导致循环依赖,所以项目是不可构建的。这样的安排并不常见,但确实有时会发生。当它发生时,你必须将 A 的测试移到一个单独的模块 C 中,该模块依赖于 A 和 B,并且只在 A 上留下生产代码。

在 maven 中,没有什么特别之处:在生产模块中您只指定 <sourceDirectory>,而在测试模块中您只指定 <testSourceDirectory>。其他一切都按预期完成:两个模块都有相同的父 pom,父 pom 引用它们。 JUnit 和其他与测试相关的依赖项仅包含在测试模块中。它是如此简单,以至于微不足道。 (我不确定 OP 面临什么样的麻烦让他提出这个问题。)

事实上,如果不是人们在持续部署期间用于运行测试的特定 maven 插件,您甚至不需要 <testSourceDirectory>,您可以在所有模块中使用 {{ 1}}。 IntelliJ IDEA 即使在 <sourceDirectory> 下检测和运行测试也没有问题,但是 maven surefire 插件确实希望测试在 <sourceDirectory> 下,因此您必须使用 <testSourceDirectory>让该插件开心。

我个人的观点是,在同一模块中支持区分生产和测试子文件夹会给构建系统带来大量完全不必要的复杂性。如果该功能根本不存在,整个 Java 世界都会做得很好。当然,这种意见是暂时的,因为我不知道可能存在重要的原因,因此这种区别是有用的。如果有人知道任何此类原因,请在评论中启发我。