考虑一个带有小型库式静态方法的Java类。
将JUnit测试方法放在同一个类中是不是很糟糕?
我看到以下专业人士:
对比是什么,为什么始终将测试代码分开是一般做法?
一个例子:
import org.junit.*;
public class HtmlUtils {
public static String normalizeBrs(String html) {
return html.replaceAll("<br\\s*/?>", "<br/>");
}
@Test
public void testNormalizeBrs() {
Assert.assertEquals(normalizeBrs("hello <br /> world <br>"), "hello <br/> world <br/>");
}
}
答案 0 :(得分:4)
(将JUnit测试方法放入测试类中是不好的做法?)
<强>绝对强>
这里的关键原因是: single responsibility principle 。编程中的类,方法,任何事物应该支持/提供一个责任。
您的生产代码的核心职责是实现其“生产目的”。
换句话说:业务逻辑是业务逻辑。没有 else 。
任何不属于该存储桶的东西...... 某处其他 。
测试是一种“事物”,方面,责任,无论你如何命名。
更典型的方法是为生产和测试代码提供不同的项目。
当你的生产类是x.y.Z ...那么测试类将是x.y.ZTest;但是虽然它们位于同一个包中,但通常会将它们放在不同的源位置文件夹中。
除此之外:对于Java来说,重构可以被视为2017年的“解决问题”。将方法转移到不同的类中,或者更改包名称是如此简单,以至于你(绝对)做到了不用担心。 (如果重构对你来说太危险了,你考虑用测试代码污染你的生产代码,那么:学习如何使用现代工具)
此外,如果您将测试方法放在测试类中,您可能最终会测试内部实现。这不是你应该测试的。你应该测试类API;你的测试应该独立于内部实现。
答案 1 :(得分:2)
如果您的包裹很小,您可能不会发现任何差异。
但是想象一下,你有一个包含1000个类的包,然后拥有数以万计的方法。意味着数以万计的测试。
那么如果将所有代码+测试放在一起会发生什么?
对于类似的东西,你最终可能会用垃圾装载内存,而垃圾实际上永远不会用于任何目的。
这就是为什么一般练习总是鼓励你将它们分开。通过遵循这个较小的包装,你实际上也在为更大的项目进行自我训练。
答案 2 :(得分:1)
我们将源代码与测试代码分开。
以下是我所知道的原因。
随意在此列表中添加更多内容。
干杯!!!
答案 3 :(得分:1)
除 nafas
的答案外将测试与源代码保持在同一位置
如果测试源与测试类保持在同一位置,则测试和类将在构建期间进行编译。这会强制您在开发期间保持测试和类的同步。实际上,未被视为正常构建的一部分的单元测试很快变得过时且无用。
http://www.javaworld.com/article/2076265/testing-debugging/junit-best-practices.html http://www.kyleblaney.com/junit-best-practices/
答案 4 :(得分:1)
如果您在生产代码中进行了测试,那么:
答案 5 :(得分:0)
一个久经考验的模型是标准Maven项目布局和许多其他构建框架所使用的模型。
我们有单独的src/main
和src/test
目录,但它们都在同一个项目中。
src/main
包含所有生产代码,没有别的。
src/test
包含单元测试。
构建配置指定依赖项,并且知道测试类和生产类之间的区别。
测试需要一些依赖项。最根本的是,jUnit本身。也像嘲笑库(JMock,Mockito),像Hamcrest这样的工具,像WireMock或RestClientDriver这样的工具,你自己的测试库等等。
您不需要这些库来运行生产代码,因此您不应将它们捆绑在构建中,也不要将构建声明为依赖项。
在测试驱动的项目中,您通常希望拥有比生产代码更多的测试代码行。所以包括测试代码会严重增加您的发行版的大小。
Maven在编译和运行测试时将测试依赖项放在类路径中,但在编译生产代码时不将它们放在类路径中。这意味着如果您尝试在生产类中使用jUnit,Mockito等,您将收到编译错误 - 这就是您想要的。
所以:
所有这些还具有Java程序员倾向于熟悉此布局的优点。程序员不要惊讶。
您的观察:
这是一个有效的观察,并且有一些写作的先例
为此原因进行内联测试。但是,它往往存在于分布式代码的大小无关紧要的环境中,或者存在剥离或忽略作为构建的一部分的测试代码的方法。例如,在C中,测试可能在#IFDEF TEST
预处理程序指令中。这样可以避免在删除“测试”代码时删除软件实际工作所需的内容 - 即仅在测试代码存在时才有效的代码!
因为Maven布局对Java程序员来说非常熟悉,所以他们知道在哪里 找单元测试。许多IDE(或插件)允许您通过击键在类及其单元测试之间切换 - 只要遵循命名约定。
在实践中,这很少是一个问题,但是一些IDE(或插件)无论如何都会使它自动化。例如,我相信在IntelliJ IDEA中,如果你重命名一个类,或者将它移动到另一个包,它的相应测试类也会被重命名或移动 - 只要你遵循命名约定。
-
我建议您采用这些完善的做法,无论是使用Maven,Gradle还是其他一些构建系统。