将JUNIT测试方法放入经过测试的类中是不好的做法



考虑带有小库式静态方法的Java类。

将JUNIT测试方法放在同一类是不好的做法吗?

我看到以下优点:

  • 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/>");
    }
}

(将JUNIT测试方法放入测试类是不好的做法吗?)

绝对

这里的关键原因:单个责任原理。一个类,方法,编程中的任何应支持/完全提供一个责任。

您的生产代码的核心责任是实现其"生产目的"。

换句话说:业务逻辑是业务逻辑。没有什么 else

任何不属于该存储桶的东西...

测试是一种"事物",方面,责任,但是您将其命名。

更典型的方法是甚至具有用于生产和测试代码的不同项目。

当您的生产类是X.Y.Z ...然后测试类是X.Y.Ztest;但是,尽管它们居住在同一包中,但通常会将它们放入不同的源位置文件夹中。

及以后:重构 java可以看作是2017年的"解决问题"。四处移动方法转移到不同的类别,或者更改的软件包名称今天是如此容易,以至于您(绝对)这样做不必为此担心。(如果重构对您来说是如此危险,以至于您考虑使用测试代码污染生产代码,那么:学习如何使用现代工具)

另外,如果将测试方法放入测试类中,则最终可能会测试内部实现。这不是您应该测试的。您应该对API类测试;您的测试应独立于内部实施。

如果您的软件包很小,您可能不会注意到任何区别。

但是,想象一下您有一个包含1000堂课的软件包,然后拥有10千种方法。意思是成千上万的测试中的10秒。

那么,如果将所有代码 测试一起进行?

将会发生什么?

对于类似的东西,您最终可能会加载内存的垃圾,这些垃圾永远不会真正实现任何目的。

这就是为什么通用实践始终鼓励您分开的原因。通过此操作以获取较小的包裹,您实际上也在培训自己的较大项目。

我们将源代码与测试代码分开。

这是我知道的原因。

  1. 我们为生产构建源代码的构建,它不应包含测试代码。代码尺寸不必要的增加。
  2. 单独的测试项目有帮助。因此,我们可以在定期间隔源后运行测试构建,以检查所有内容是否在检查中。例如一般实践是,当您进行代码更改并推动代码时,这些测试构建会触发,然后检查您的新更改。
  3. 测试用例仅用于内部用途,只是确保我们保持代码的质量。大多数对此不感兴趣的客户。

随时在此列表中添加更多。

欢呼!

除了 nafas

的答案外

将测试保持与源代码

的位置

如果测试源与测试类相同的位置,则测试和类都将在构建过程中进行编译。这迫使您在开发过程中保持测试和类同步。实际上,单位测试不被认为是正常构建的一部分,很快就会过时且毫无用处。

http://www.javaworld.com/article/2076265/testing-debugging/junit-best-practices.htmlhttp://www.kyleblaney.com/junit-best-practices/practices/pp>

如果您在生产代码中有测试,则:

  1. 您将有其他依赖关系(因此,jar/war/ear文件的尺寸更大,更多的时间加载,需要更多的内存ressources)(例如,莫科托,...),这绝对是不必要的申请
  2. 您将在类中具有其他属性,需要内存ressources,并且可能与应用程序属性的属性相抵触
  3. 测试方法必须公开,因此测试方法是您生产代码API的一部分(对于想要使用您的应用程序代码的人来说,这是完全混淆的)
  4. 班级变得越来越困难
  5. 您正在伤害惯例,例如

一个尝试和测试的模型是标准Maven项目布局和许多其他构建框架使用的模型。

我们有单独的src/mainsrc/test目录,但它们都在同一项目中。

src/main包含所有生产代码,没有其他。

src/test包含单元测试。

构建配置指定依赖项,并且知道测试类和生产类之间的区别。

测试需要一些依赖项。从根本上讲,Junit本身。还想像嘲笑库(JMOCK,MOCKITO),HAMCREST这样的公用事业,Wiremock或RestClientDriver等工具,您自己的测试库,等等。

您不需要这些库即可运行生产代码,因此您不应该将它们捆绑在构建中,也不应将其声明为依赖关系。

在一个测试驱动的项目中,您通常期望比生产代码拥有更多的测试代码行。因此,包括测试代码将严重增加您的分布的大小。

Maven在编译和运行测试时将测试依赖项放在类路径中,但是在编译生产代码时,不是将它们放在类路径上。这意味着,如果您尝试使用Junit,Mockito等。

so:

  • 生产代码及其相应的测试在同一项目中在单独的目录中
  • 构建分布包括编译和运行测试
  • 构建的伪像没有比必要的大,因为它不包括测试代码

所有这些都具有Java程序员倾向于熟悉这种布局的优势。程序员喜欢不要感到惊讶。

您的观察:

  • " Junit测试作为自我文献的方法就在方法代码附近"

这是一个有效的观察,并且有一些先例出于这个原因进行内联测试。但是,它往往是在分布式代码大小无关紧要的环境中,或者有一种方法可以剥离或忽略测试代码作为构建的一部分。例如,在C中,测试可能是在#IFDEF TEST预处理器指令中。这有一个风险,即当您删除"测试"代码时,您会删除软件工作实际所需的内容 - 即仅在存在测试代码时工作的代码!

因为Java程序员的Maven布局是如此熟悉,所以他们知道在哪里查找单元测试。许多IDE(或插件)允许您使用击键在类及其单元测试之间切换 - 只要您遵循命名约定。

  • "将此代码移至另一个类或软件包很容易"

实际上,这很少是一个问题,但是无论如何,有些IDE(或插件)自动化它。例如,我相信,在Intellij Idea中,如果您重命名了类或将其移至另一个软件包,则其相应的测试类也会重命名或移动 - 只要您遵循命名约定。

-

我的建议是,无论是使用Maven,Gradle还是其他一些构建系统。

最新更新