1

上周我发现自己不得不开始考虑如何重构一个只包含单元测试的旧应用程序。我的第一个想法是使用 Cucumber 添加一些组件测试场景,以熟悉业务逻辑并确保我的更改不会破坏任何内容。但那时我与我工作的公司的一位架构师进行了交谈,这让我想知道这是否值得,以及我必须实际测试的代码到底是什么。

此应用程序有许多不同类型的端点:要调用和调用的其余端点、Oracle 存储过程和 JMS 主题和队列。它部署在 Tomcat 服务器的 war 文件中,到代理的连接工厂和到数据库的数据源在服务器中配置并使用 JNDI 获取。

我的第一个想法是在嵌入式 Jetty 中加载整个应用程序,指向真正的 web.xml,以便加载所有内容,就像从生产环境加载一样,然后模拟连接工厂和数据源。通过这样做,将测试部署应用程序的基础设施的所有连接逻辑。考虑到六边形架构,考虑到这些只是逻辑应该只是将接收到的数据转换为应用程序数据的端口,这似乎太过分了。这不应该只是单元测试吗?

我的下一个想法是在我的测试中模拟存储过程并在没有任何 Web 服务器的情况下加载 Spring XML,这使得模拟类更容易。为此,我将使用 Spring MockMvc 等库作为其余端点,将 Mockrunner 用于 JMS。但同样,这种方法仍然会测试一些适配器并使测试复杂化,因为测试的结果将是 XML 和 JSON 有效负载。在此应用程序中完成的转换非常繁重,其中相同的消息类型可能包含不同版本的类(每个消息可能包含许多实现多个接口的复杂对象)。

所以现在我在想,也许最好的方法是创建从入口点到应用程序的测试,从适配器调用的服务,并验证负责向代理发送消息或调用其他 REST 的服务实际上调用了端点。然后只需确保对端点进行适当的单元测试,并通过提供一些在真实环境中执行的冒烟测试来验证部署后一切正常。这将测试连接逻辑,并且将单独测试业务逻辑,而不关心是否添加了新适配器或删除了适配器。

这种方法正确吗?我会在不以这种方式测试的情况下留下一些东西吗?还是还是太多了,我应该相信单元测试?

谢谢。

4

1 回答 1

1

您的应用程序和环境听起来相当复杂。我肯定想要集成测试。我将按如下方式从外到内测试应用程序:

  • 编写一个针对实际生产环境中的应用程序运行的冒烟测试套件。黄瓜将是一个很好的工具。该套件应该只做在生产中安全的事情,并且应该尽可能小,同时让您确信应用程序已正确安装和配置,并且它与其他系统的集成正在工作。

  • 编写一个在测试环境中针对整个应用程序运行的验收测试套件。黄瓜在这里也是一个不错的选择。

    我希望验收测试环境包括一个 Tomcat 服务器,其中包含生产 Tomcat 中存在的所有服务的测试版本,以及一个具有与生产(但不是生产数据)相同的模式、存储过程等的数据库。通过存根和模拟、使用记录/重放库(如Betamax )和/或自己实现它们的测试版本来处理您不拥有的外部依赖项。验收测试应该可以自由地对数据做任何事情,他们不应该担心您不拥有的服务的可用性。

    编写足够的验收测试来描述应用程序的主要用例并测试应用程序各部分(子系统和类)之间的所有重要交互。也就是说,将您的验收测试用作集成测试。我发现验收测试和集成测试的目标之间几乎没有冲突。但是,不要编写超出规范和集成覆盖范围所需的验收测试,因为它们相对较慢。

  • 对每个做任何有趣事情的类进行单元测试,只漏掉那些经过验收测试完全测试的类。由于您已经在进行集成测试,因此您的单元测试可以是真正的单元测试,可以存根或模拟它们的依赖关系。(尽管让一个单元测试的类使用真正的依赖关系并没有错,这些依赖关系足够简单,不会在单元测试中引起问题)。

测量代码覆盖率以确保验收和单元测试的组合测试您的所有代码。

于 2016-03-12T20:47:39.810 回答