Java 单元测试,目录布局

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

例如,如果我有一个包含大量 .java源文件的目录 /java,是将测试用例放在 /java本身中更好,还是使用类似于 /java/test的东西更好。

如果首选后者,当类的 private/protected成员在包外不可用时,如何测试代码的内部结构?

83634 次浏览

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

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

您可以在 src下声明一个类 com.foo.MyClass,在 test下声明它的测试 com.foo.MyClassTest

至于对私有成员的访问,您可以使用 反思来调用这些方法(通过 Class.getDeclaredMethod.setAccessible改变它们的可访问性) ,或者您可以使用 testng/junit5之类的东西来对源代码本身进行一些注释驱动的测试(我个人认为这是一个坏主意)。

为什么不查看一下 java.net上的一些项目,看看它们是如何组织事情的,例如 < strong > swinglab (我担心 SVN 存储库非常慢) ?

大多数时候是这样做的:

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

因此,将它们分开,仍然可以测试包/受保护的功能,因为测试在同一个包中。

您不能测试私有内容,除非它在类自身中声明。

在交付时,您只需打包由 src 生成的 .class,而不是测试

我建议按照 Apache软件基金会的标准目录结构,其结果如下:

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

这使得测试与源代码分离,但是在目录结构的相同级别上。如果您仔细阅读 Apache 如何定义它们的结构,您将看到它也有助于将其他问题划分出来,包括资源、配置文件、其他语言等。

此结构还允许单元测试测试被测单元的包和受保护级别方法,假设您将测试用例放置在与它们测试的包相同的包中。关于测试私有方法-我不会麻烦。其他的东西,不管是公共的、软件包的还是受保护的,都可以调用它们,您应该能够获得测试这些东西的完整测试覆盖率。

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

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

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

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

此方法可确保测试代码依赖项不会污染生产代码。

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

我们就是这么安排的,我们很喜欢。

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

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

安卓工作室中创建 Java 库模块时,它会在下面创建一个默认类:

[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]

上面的结构将被 安卓工作室识别,下面的文件将被包含到模块中。

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