如何为 Arquillian UI 测试重置数据库
Posted
技术标签:
【中文标题】如何为 Arquillian UI 测试重置数据库【英文标题】:How to reset the database for Arquillian UI tests 【发布时间】:2015-01-23 17:29:20 【问题描述】:我有一个带有 JPA/Eclipselink 的默认 Java EE 7 应用程序。 我想用 Arquillian Drone/Graphene 编写一些 UI 测试。
我的测试套件正在“工作”。我可以点击应用程序并做出一些断言。
但是:我想创建多个测试。每个测试类都应该重置数据库,以确保条件始终相同。
我正在使用 flyway 来重置我的数据库。
@Before
public void setup()
Flyway flyway = new Flyway();
flyway.setDataSource(...);
flyway.clean();
flyway.init();
flyway.migrate();
重置正在工作。并且测试的第一次执行也是(在这种情况下,任何缓存中都没有任何内容)。 当我再次尝试执行测试时,数据库与奇怪的 JPA 错误不一致。 首先我认为可以:重置缓存
getEntityManager().getEntityManagerFactory().getCache().evictAll();
还不够。同样的问题。 下一个想法是销毁会话(一些 JPA 数据可以保存在旧会话中)。我还没有找到销毁所有会话的好方法。我做了一个解决方法,但这也不起作用。
我认为我有一个默认问题,但我找不到任何解决此问题的方法。
我还尝试了 dbunit 和 arquillian-persistence-extension。但这就像飞行路线,只是另一种方式。
理论上的问题是,数据库已通过 SQL 手动重置,而 Java/JPA/EclipseLink/The Sessions/deployed applaction 不知道更改的数据。 如何重置所有内容(所有缓存?)?
我还考虑过“在开始测试类之前重新部署”。但这有点过分(需要更多时间并且不是很好的解决方案)?
更多信息:我也在进行正常的 arquillian-tests(没有 UI/Selenium),这是我的 flyway 数据库重置工作。
感谢您的帮助:)。
【问题讨论】:
也许从发布奇怪的 JPA 问题开始,因为它们是意料之外的,并且可能指向不同的根本原因。另外,您是持有同一个 EntityManager 还是每次测试都获得一个新的? 一个错误例如:org.postgresql.util.PSQLException: 错误: 重复键值违反唯一约束 »abstractentity_pkey« 详细信息: 键 »(id)=(29420)« 已存在序列/seq_count在数据库中具有正确的值。一定是……在一些缓存中。 在我的测试套件中,我没有实体管理器(我正在使用 jdbc 连接来重置它)。在我的应用程序中,我有 @PersistenceContext(unitName = "mydatabasePU") private EntityManager em;我认为持久性上下文是每个用户会话创建的。我不能在测试套件中重用上下文? 【参考方案1】:你没有说你真正遇到了什么错误,你只是说:
当我再次尝试执行测试时,数据库与奇怪的 JPA 错误不一致(...)
很难相信您的问题在于 JPA 缓存。我认为你的问题有完全不同的来源。
您清理数据库的方法存在根本缺陷。
您提供的代码:应该在所有测试之前只运行一次。因为Flyway
是为了准备数据库结构,而不是将其设置为已知状态。
所以从概念上讲 DbUnit
& Arquillian Persistence Extension
和 Flyway
做两件真正不同的事情。
它们不能相互替代。
所以你使用flyway的代码:
@Before
public void setup()
...
flyway.clean();
flyway.init();
flyway.migrate();
是错误的,因为它应该在所有测试之前只运行一次。为此,您可以使用一些容器功能:
-
如果使用EJB Container,则可以使用
@Singleton
+ @Startup
+ @PostConstruct
组合来启动flyway工具。
如果使用 Spring Container,那么 init-method="migrate"
就可以了。
或使用maven
及其pre-integration-test
阶段启动flyway 工具。
顺便说一句:为了避免与 DbUnit 的 xml 数据集相关的维护工作,我个人推荐DbSetup 工具。不错且简单的解决方案。
编辑
除此之外,在测试期间更改数据库结构并不是一个好习惯 - 您的问题也可能是因为 Flyway 和 JPA 使用不同的数据源(甚至指向同一个数据库)。您应该仔细检查您没有自己创建 DataSource - 只需为 Flyway 注入 PersistenceUnit 正在使用的同一个。
【讨论】:
我也可以使用@BeforeClass,这是在类中的所有测试执行之前运行的。只有一次。但是错误是一样的。所有重置工具都使用额外的 jdbc 连接。 Java 应用程序对数据库更改一无所知。我需要的是:如何告诉应用程序,数据库已更改,所有内容都应刷新/重置? 不完全是,@BeforeClass 在每个测试类之前启动 - 所以它仍然太多。我不知道为什么你在测试期间改变了整个数据库结构。这不是一个好习惯。 我有多个 UI 测试类。每个 UI 测试类都应该从相同的干净情况开始,因为 Test1 正在创建一些会与 Test2 冲突的数据。所以我想为每个班级重置数据库。在一个测试类之后删除所有新数据是一个复杂的话题。一个测试类正在创建大量数据库条目(具有很多约束的多个表中的 250-500 个条目)我认为 flyway sql dump reset 是创建干净数据库的最简单方法。 重新创建数据库不同于从所有表中删除所有记录。请考虑后一种(DbSetup 或 Arquillian Persistence Extension 可能会有用)。 设置相同的数据源是有效的。 @Resource(lookup = "mydatasource") 私有数据源数据源; flyway.setDataSoruce(数据源);感谢您的帮助以上是关于如何为 Arquillian UI 测试重置数据库的主要内容,如果未能解决你的问题,请参考以下文章
如何为不同环境的 SwiftUI App 生命周期应用程序运行 UI 测试?