集成测试
在不需要部署到应用服务器或连接其他企业级基础设施的情况下进行集成测试非常重要。 这样可以测试以下内容:
-
Infra IoC 容器上下文的正确装配。
-
使用 JDBC 或 ORM 工具进行数据访问的正确性。这可以包括 SQL 语句、Hibernate 查询、 JPA 实体映射等。
TODAY Framework 在 infra-test 模块中提供一流的集成测试支持。实际 JAR 文件名可能包含
发布版本号,也可能采用较长的 infra.test 形式,取决于你获取它的方式
(参见 依赖管理章节 了解说明)。该库包含
infra.test 包,其中提供了对 Infra 容器进行集成测试的有用类。这类测试不依赖应用服务器或
其他部署环境。其运行速度比单元测试慢,但远快于依赖部署到应用服务器的等效 Selenium 测试
或远程测试。
单元与集成测试支持通过注解驱动的 Infra TestContext Framework 提供。TestContext 框架与具体测试框架无关,可在 JUnit、TestNG 等多种环境中对测试进行装配。
以下内容概述 Infra 集成测试支持的高级目标,章节余下部分将聚焦于以下专题:
集成测试目标
Infra 集成测试支持的主要目标包括:
-
在测试之间管理 Infra IoC 容器缓存。
-
提供 测试夹具实例的依赖注入。
-
提供适合集成测试的 事务管理。
-
提供 Infra 专用基类,帮助开发者编写集成测试。
接下来几节将逐一说明这些目标,并给出实现与配置的细节链接。
上下文管理与缓存
Infra TestContext Framework 提供对 Infra ApplicationContext 与 WebApplicationContext
的加载与一致缓存。缓存加载的上下文很重要,因为启动时间可能成为问题——并非 Infra 本身的
开销,而是 Infra 容器实例化对象所需的时间。例如,一个包含 50 到 100 个 Hibernate 映射
文件的项目可能需要 10 到 20 秒加载映射文件;如果每个测试夹具在运行前都要承担这个成本,
将导致整体测试运行变慢并降低开发效率。
测试类通常声明一组资源位置(XML 或 Groovy 配置元数据,通常在 classpath 中),或一组
组件类用于配置应用。这些位置或类与生产部署中 web.xml 或其他配置文件中指定的内容相同或
相似。
默认情况下,配置好的 ApplicationContext 在加载后会在每个测试中复用。因此,初始化成本
仅在每个测试套件中发生一次,后续测试执行更快。这里“测试套件”指在同一 JVM 中运行的所有
测试,例如某个项目或模块的 Ant、Maven 或 Gradle 构建中执行的所有测试。在极少数情况下,
如果测试破坏了应用上下文并需要重新加载(例如修改了 bean 定义或应用对象状态),
TestContext 框架可以配置为在执行下一个测试前重新加载配置并重建应用上下文。
测试夹具的依赖注入
当 TestContext 框架加载应用上下文时,它可以选择通过依赖注入来配置测试类实例。这提供了
一个便捷机制,可以使用来自应用上下文的预配置 bean 来设置测试夹具。其优势在于可以在多种
测试场景中复用应用上下文(例如用于配置 Infra 管理的对象图、事务代理、DataSource
实例等),从而避免为单个测试用例重复搭建复杂的测试夹具。
例如,考虑一个实现 Title 领域实体数据访问逻辑的类(HibernateTitleRepository)。
我们希望编写集成测试来验证以下方面:
-
Infra 配置:与
HibernateTitleRepositorybean 配置相关的内容是否正确且齐全? -
Hibernate 映射文件配置:映射是否正确、懒加载设置是否正确?
-
HibernateTitleRepository的逻辑:该类的配置实例是否按预期工作?
参见 TestContext framework 中的测试夹具依赖注入。
事务管理
在访问真实数据库的测试中,一个常见问题是它们对持久化存储状态的影响。即使使用开发数据库, 状态变化也可能影响后续测试。此外,许多操作(例如插入或修改持久化数据)无法在事务之外 执行或验证。
TestContext 框架解决了该问题。默认情况下,框架为每个测试创建并在结束时回滚事务。你可以
编写假设事务存在的代码。如果在测试中调用经过事务代理的对象,它们会按照配置的事务语义
正确运行。此外,如果测试方法在由测试管理的事务中删除了特定表的数据,事务默认回滚,
数据库会恢复到测试执行前的状态。测试的事务支持通过在测试的应用上下文中定义
PlatformTransactionManager bean 来提供。
如果希望事务提交(不常见,但在需要让测试填充或修改数据库时偶尔有用),可以使用
@Commit 注解,让 TestContext 框架提交事务而不是回滚。
参见 TestContext framework 中的事务管理。
集成测试的支持类
Infra TestContext Framework 提供若干 abstract 支持类,简化集成测试的编写。
这些基础测试类提供了与测试框架的明确钩子,以及便捷的实例变量和方法,使你能够访问:
-
ApplicationContext,用于显式查找 bean 或测试上下文整体状态。 -
JdbcTemplate,用于执行 SQL 查询数据库。你可以在执行与数据库相关的应用代码前后 确认数据库状态,Infra 确保这些查询在与应用代码相同的事务范围内执行。与 ORM 工具结合 使用时,应避免 误报。
另外,你可能希望创建一个自定义的、应用范围内的超类,包含适合项目的实例变量和方法。
参见 TestContext framework 中的支持类。