Java单元测试,目录布局


76

在为Java代码构建一套单元测试时,是否有关于将测试代码与源代码放置在何处的约定?

例如,如果我有一个/java包含一堆.java源文件的目录,那么最好将测试用例/java本身放在其中或使用类似的内容/java/test

如果首选后者,那么在包外部无法使用类的private /protected成员时,如何测试代码的内部?

Answers:


73

您可以将测试与原始类放在同一包中,即使源代码位于其自己的目录根目录下:

PROJECT_ROOT
    +--- src/
    +----test/

你可以声明一个类com.foo.MyClasssrc其测试com.foo.MyClassTesttest

至于访问私有成员,您可以使用反射来调用方法(通过来更改方法的可访问性Class.getDeclaredMethod.setAccessible),也可以使用诸如testng / junit5之类的方法在源代码本身上进行一些注释驱动的测试(我个人认为这是一个馊主意)。

为什么不检查一些项目java.net以了解它们是如何组织的,例如swinglabs(恐怕SVN存储库非常慢)?


117

我建议遵循Apache Software Foundation的标准目录结构,它会产生以下结果:

module/
  src/
    main/
      java/
    test/
      java/

这使测试与源代码分开,但在目录结构中处于同一级别。如果通读Apache如何定义其结构,您会发现它也有助于将其他顾虑进行分区,包括资源,配置文件,其他语言等。

假设您将测试用例与测试用例放在同一包中,则此结构还允许单元测试对被测单元的打包和保护级别方法进行测试。关于测试私有方法-我不会打扰。其他的东西,无论是公共的,打包的还是受保护的,都可以调用它们,您应该能够对这些内容进行全面的测试。

顺便说一下,上面的链接是Apache的标准构建工具Maven。他们拥有的每个Java项目都符合该标准,而我遇到的每个由Maven构建的项目都符合该标准。


6
+1即使您不使用Maven,也最好遵循这种布局(一种基于行业最佳实践的事实上的标准)。
Pascal Thivent 09年

7
这里提到Maven的唯一原因是因为它的网站是记录Apache标准目录布局的地方。您喜欢或不喜欢的内容与所讨论的目录结构是否良好无关。也许您可以评论与您的​​意见相符的答案,以表明该目录结构为何优越。
SingleShot

1
如果您使用纯Java进行编码,则该java目录是不必要的添加
oxbow_lakes

6
值得一提的是,通常maintest文件夹都具有一个resources源文件夹,该文件夹可以编译到与该java文件夹相同的输出文件夹中,从而可以在源级别轻松分离Java代码和资源文件。我也喜欢这种结构,因为它使顶层没有多个源文件夹……这是一个非常合乎逻辑的组织。是的,这与是否喜欢Maven无关。
ColinD

3
我八年前发表了这一评论。从那以后,我逐渐了解并热爱Maven。如果没有它,我将无法工作。人们可以改变。
duffymo

8

大多数时候是这样完成的:

<SOME_DIR>/project/src/com/foo/Application.java
<SOME_DIR>/project/test/com/foo/ApplicationTest.java

因此,您可以将它们分开,并且由于测试位于同一程序包中,因此您仍然可以测试程序包/受保护的功能。

您不能测试私有的东西,除非它在自己的类中声明。

交付后,您只需打包.classsrc生成的包,而不是测试包


1
测试应该在src文件夹中。maven.apache.org/guides/introduction/…–
菲利普·雷戈

5

实际上,将生产和测试项目分成两个单独的实体很有意义,但是在两个项目中都具有相同的包结构。

因此,如果我有一个项目“ my-project”,我还将创建“ my-project-test”,因此我具有以下目录结构:

my-project
  +--- src/com/foo
my-project-test
  +---test/com/foo

这种方法确保测试代码依赖性不会污染生产代码。

我个人认为,应该对包私有和受保护的方法以及公共方法进行测试。因此,我希望测试类与生产类在同一包中。


2

这就是我们设置它的方式,我们喜欢它。

build/
src/
test/build/
test/src/

所有测试代码都编译到其自己的构建目录中。这是因为我们不希望生产错误地包含测试类。


1

当创建一个Java库模块的Android工作室它创造下一个默认的类:

[module]
   + src/main/java/[com/foo/bar]

如果您查看[module].iml文件,则会发现该路径以及可以利用的测试路径。以下是摘要:

<module>
  <component>
    <content>
      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
    </content>
  </component>
</module>

您特别可以做的是为测试创建目录,使其具有以下结构:

[module]
   + src/main/java/[com/foo/bar]
   + src/test/java/[com/foo/bar]

上面的结构将被Android Studio识别,并且您下面的文件将包含在模块中。

我认为该结构是代码和测试的推荐布局。

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.