【发布时间】:2009-10-08 20:43:33
【问题描述】:
在为 Java 代码构建一套单元测试时,是否有关于将测试代码与源代码相关的放置位置的约定?
例如,如果我有一个目录/java 包含一堆.java 源文件,那么最好将测试用例放在/java 本身中还是使用类似/java/test 的东西。
如果首选后者,当类的private /protected 成员在包外不可用时,如何测试代码的内部?
【问题讨论】:
标签: java unit-testing
在为 Java 代码构建一套单元测试时,是否有关于将测试代码与源代码相关的放置位置的约定?
例如,如果我有一个目录/java 包含一堆.java 源文件,那么最好将测试用例放在/java 本身中还是使用类似/java/test 的东西。
如果首选后者,当类的private /protected 成员在包外不可用时,如何测试代码的内部?
【问题讨论】:
标签: java unit-testing
我建议关注Apache Software Foundation's standard directory structure,这会产生:
module/
src/
main/
java/
test/
java/
这使测试与源代码分开,但在目录结构中处于同一级别。如果您仔细阅读 Apache 如何定义它们的结构,您会发现它也有助于划分其他问题,包括资源、配置文件、其他语言等。
这种结构还允许单元测试测试被测单元的包和受保护级别的方法,假设您将测试用例放在与它们测试的包相同的包中。关于测试私有方法 - 我不会打扰。其他东西,无论是公共的、包的还是受保护的都会调用它们,您应该能够获得完整的测试覆盖率来测试这些东西。
顺便说一下,上面的链接是 Maven,Apache 的标准构建工具。他们的每个 Java 项目都符合这个标准,我遇到的每个项目都是用 Maven 构建的。
【讨论】:
java目录是不必要的添加
main 和test 文件夹都有一个resources 源文件夹,它编译到与java 文件夹相同的输出文件夹中,可以轻松分离源代码级别的 Java 代码和资源文件。我也喜欢这种结构,因为它使顶层没有多个源文件夹……这是一个非常合乎逻辑的组织。是的,这与是否喜欢 Maven 无关。
您可以将测试与原始类放在同一个包中,即使源代码位于其自己的根目录下:
PROJECT_ROOT
+--- src/
+----test/
您可以在src 下声明一个类com.foo.MyClass,在test 下声明它的测试com.foo.MyClassTest。
对于私有成员的访问,你可以使用 reflection 来调用方法(通过Class.getDeclaredMethod.setAccessible 改变它们的可访问性),或者你可以使用类似 testng/junit5 的东西来放置一些注解驱动的对源代码本身进行测试(我个人认为这是一个坏主意)。
为什么不在java.net 上查看一些项目,看看他们是如何组织的,例如swinglabs(恐怕SVN 存储库很慢)?
【讨论】:
大多数时候都是这样的:
<SOME_DIR>/project/src/com/foo/Application.java
<SOME_DIR>/project/test/com/foo/ApplicationTest.java
因此,您将它们分开,您仍然可以测试包/受保护的功能,因为测试在同一个包中。
你不能测试私有的东西,除非它在它自己的类中声明。
交付时,您只需打包 src 生成的.class,而不是测试
【讨论】:
实际上,将您的生产和测试项目分成 2 个独立的实体非常有意义,但在两个项目中具有相同的包结构。
所以如果我有一个项目“my-project”,我也会创建“my-project-test”,所以我有以下目录结构:
my-project
+--- src/com/foo
my-project-test
+---test/com/foo
这种方法可确保测试代码依赖项不会污染生产代码。
在我个人看来,应该测试包私有和受保护的方法以及公共方法。因此,我希望我的测试类与生产类在同一个包中。
【讨论】:
这就是我们设置它的方式,我们喜欢它。
build/
src/
test/build/
test/src/
所有测试代码都编译到它自己的构建目录中。这是因为我们不希望生产环境错误地包含测试类。
【讨论】:
在Android Studio 中创建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]
上面的结构会被Android Studio识别,你下面的文件会被包含到模块中。
我认为该结构是推荐的代码和测试布局。
【讨论】: