如何为 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 ExtensionFlyway 做两件真正不同的事情。 它们不能相互替代。

所以你使用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 测试?

如何为更长的网页编写 UI 手动测试用例?

如何为 SwiftUI InputField 编写 UI 测试

如何为 Xcode UI 测试禁用沙箱

如何为 Flash 进行自动化 UI 测试 [关闭]

如何为编码的 UI 测试设置文化以从资源文件中获取本地化文本?