Java 用JUnit编写系统测试 前言

Java 用JUnit编写系统测试 前言,java,junit,junit5,Java,Junit,Junit5,我在深思熟虑地谈论系统测试。我们确实有一套相当详尽的单元测试,其中一些使用模拟,而这些都不会用到任何地方。系统测试应该是对单元测试的补充,因此模拟不是一个选项 问题 我有一个相当复杂的系统,它只通过REST和websocket事件进行通信。 我的团队有一个相当大的基于JUnit的(历史上增长的)系统测试集合。 我目前正在将此代码库迁移到JUnit5 测试通常包括一个@BeforeAll,其中系统在特定于测试类的配置中启动,这大约需要一分钟。然后在这个系统上进行了一些独立的测试 我们经常遇到的问题

我在深思熟虑地谈论系统测试。我们确实有一套相当详尽的单元测试,其中一些使用模拟,而这些都不会用到任何地方。系统测试应该是对单元测试的补充,因此模拟不是一个选项

问题 我有一个相当复杂的系统,它只通过REST和websocket事件进行通信。 我的团队有一个相当大的基于JUnit的(历史上增长的)系统测试集合。 我目前正在将此代码库迁移到JUnit5

测试通常包括一个
@BeforeAll
,其中系统在特定于测试类的配置中启动,这大约需要一分钟。然后在这个系统上进行了一些独立的测试

我们经常遇到的问题是引导系统需要相当长的时间,甚至可能失败。可以说,引导本身可以被视为一个测试用例。JUnit处理生命周期方法有点奇怪——报告中没有显示它们花费的时间;如果他们失败了,这会影响测试的计数;它不是描述性的;等等

我目前正在寻找一种解决方法,但我的团队在过去几年中所做的工作与JUnit的核心思想是正交的(因为它是一个单元测试框架)

如果我用一个测试方法(我们称之为
@testpublic void boot(){…}
)替换
@beforeal
),并引入一个顺序依赖项(使用JUnit 5非常容易),强制在运行任何其他测试之前运行
boot
,那么这些问题就会消失

到目前为止还不错!这看起来很好用。当测试不是由CI服务器执行,而是由尝试进行故障排除的开发人员执行时,实际问题就开始了。当我尝试启动单个测试时,
boot
会从测试执行中过滤出来,测试失败

JUnit5中是否有解决方案?还是我应该采取完全不同的方法


我怀疑使用
@TestTemplate
可能有一个解决方案,但我真的不知道如何处理。另外,这只允许我生成新的命名测试,这些测试也将被过滤。我必须编写一个定制的测试引擎吗?这似乎并不令人信服。

这个更一般的测试问题与Junit5有关。为了跳过很长的启动时间,如果可能的话,您可以模拟一些组件。将引导系统作为测试是没有意义的,因为还有其他测试依赖于此。在本例中,最好像以前一样使用@beforeAll。对于测试启动,您可以为将完全独立于其他测试运行的测试类创建单独的测试类。 另一个选项是将此类测试分组,并与普通单元测试分离,仅在需要时运行它(例如在CI服务器上部署之前)。这实际上取决于特定的用例,并且这些测试应该是本地机器上常规构建的一部分


第三种选择是尽可能减少启动时间。如果您不能使用mock/stub或从常规构建中排除这些测试,那么这是一个选项。

这个更一般的测试问题与Junit5有关。为了跳过很长的启动时间,如果可能的话,您可以模拟一些组件。将引导系统作为测试是没有意义的,因为还有其他测试依赖于此。在本例中,最好像以前一样使用@beforeAll。对于测试启动,您可以为将完全独立于其他测试运行的测试类创建单独的测试类。 另一个选项是将此类测试分组,并与普通单元测试分离,仅在需要时运行它(例如在CI服务器上部署之前)。这实际上取决于特定的用例,并且这些测试应该是本地机器上常规构建的一部分


第三种选择是尽可能减少启动时间。如果您不能使用mock/stub或从常规构建中排除这些测试,这是一个选项。

这是一个使用依赖项注入并提供mock/stub的选项,这样您就不需要启动整个工作环境了吗?我正在仔细讨论系统测试。我们确实有一套相当详尽的单元测试,其中一些使用模拟,而这些都不会用到任何地方。系统测试应该是对单元测试的补充,因此模拟不是一个选项。它是一个使用依赖注入并提供模拟/存根的选项,这样您就不需要启动整个工作环境了吗?我正在仔细讨论系统测试。我们确实有一套相当详尽的单元测试,其中一些使用模拟,而这些都不会用到任何地方。系统测试应该是对单元测试的补充,因此模拟不是一个选项。因此,你慷慨的建议是做单元测试,这一点都没有帮助。很抱歉,我没有告诉你用单元测试代替系统测试。我的问题非常针对JUnit5,是关于系统测试的。所以你慷慨地建议改为进行单元测试一点帮助都没有。对不起,我没有告诉你用单元测试代替系统测试。