在为Java代码构建一套单元测试时,是否有关于将测试代码与源代码放置在何处的约定?
例如,如果我有一个/java
包含一堆.java
源文件的目录,那么最好将测试用例/java
本身放在其中或使用类似的内容/java/test
。
如果首选后者,那么在包外部无法使用类的private
/protected
成员时,如何测试代码的内部?
Answers:
您可以将测试与原始类放在同一包中,即使源代码位于其自己的目录根目录下:
PROJECT_ROOT
+--- src/
+----test/
你可以声明一个类com.foo.MyClass
下src
其测试com.foo.MyClassTest
下test
。
至于访问私有成员,您可以使用反射来调用方法(通过来更改方法的可访问性Class.getDeclaredMethod.setAccessible
),也可以使用诸如testng / junit5之类的方法在源代码本身上进行一些注释驱动的测试(我个人认为这是一个馊主意)。
为什么不检查一些项目java.net
以了解它们是如何组织的,例如swinglabs(恐怕SVN存储库非常慢)?
我建议遵循Apache Software Foundation的标准目录结构,它会产生以下结果:
module/
src/
main/
java/
test/
java/
这使测试与源代码分开,但在目录结构中处于同一级别。如果通读Apache如何定义其结构,您会发现它也有助于将其他顾虑进行分区,包括资源,配置文件,其他语言等。
假设您将测试用例与测试用例放在同一包中,则此结构还允许单元测试对被测单元的打包和保护级别方法进行测试。关于测试私有方法-我不会打扰。其他的东西,无论是公共的,打包的还是受保护的,都可以调用它们,您应该能够对这些内容进行全面的测试。
顺便说一下,上面的链接是Apache的标准构建工具Maven。他们拥有的每个Java项目都符合该标准,而我遇到的每个由Maven构建的项目都符合该标准。
java
目录是不必要的添加
main
和test
文件夹都具有一个resources
源文件夹,该文件夹可以编译到与该java
文件夹相同的输出文件夹中,从而可以在源级别轻松分离Java代码和资源文件。我也喜欢这种结构,因为它使顶层没有多个源文件夹……这是一个非常合乎逻辑的组织。是的,这与是否喜欢Maven无关。
大多数时候是这样完成的:
<SOME_DIR>/project/src/com/foo/Application.java
<SOME_DIR>/project/test/com/foo/ApplicationTest.java
因此,您可以将它们分开,并且由于测试位于同一程序包中,因此您仍然可以测试程序包/受保护的功能。
您不能测试私有的东西,除非它在自己的类中声明。
交付后,您只需打包.class
src生成的包,而不是测试包
实际上,将生产和测试项目分成两个单独的实体很有意义,但是在两个项目中都具有相同的包结构。
因此,如果我有一个项目“ my-project”,我还将创建“ my-project-test”,因此我具有以下目录结构:
my-project
+--- src/com/foo
my-project-test
+---test/com/foo
这种方法确保测试代码依赖性不会污染生产代码。
我个人认为,应该对包私有和受保护的方法以及公共方法进行测试。因此,我希望测试类与生产类在同一包中。
当创建一个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识别,并且您下面的文件将包含在模块中。
我认为该结构是代码和测试的推荐布局。