Jpa 如何为Arquillian UI测试重置数据库

Jpa 如何为Arquillian UI测试重置数据库,jpa,eclipselink,flyway,jboss-arquillian,Jpa,Eclipselink,Flyway,Jboss Arquillian,我有一个带有JPA/Eclipselink的默认JavaEE7应用程序。 我想用Arquillian无人机/石墨烯编写一些UI测试 我的测试套件正在“工作”。我可以点击应用程序并进行一些断言 但是:我想创建多个测试。每个测试类都应该重置数据库,以确保条件始终相同 我正在使用flyway重置我的数据库 @Before public void setup() { Flyway flyway = new Flyway(); flyway.setDataSource(...); flyway.cl

我有一个带有JPA/Eclipselink的默认JavaEE7应用程序。 我想用Arquillian无人机/石墨烯编写一些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持久性扩展。但这就像飞行路线,只是另一种方式

理论上,问题在于,数据库已经通过SQL手动重置,而Java/JPA/EclipseLink/Sessions/deployed applaction不知道更改的数据。 如何重置所有内容(所有缓存?)

我还考虑过“在开始testclass之前重新部署”。但这是一个有点多(需要更多的时间,并不是很好的解决方案)

还有一个信息:我也在做正常的arquillian测试(没有UI/Selenium),下面是我的flyway数据库重置工作


谢谢你的帮助:)。

你没有说你到底犯了什么错误,你只是说:

当我再次尝试执行测试时,数据库与奇怪的JPA错误不一致(…)

很难相信您的问题在于JPA缓存。我认为你的问题有完全不同的根源

清理数据库的方法有一个基本缺陷。 您展示的代码:在所有测试之前,应该只运行一次。因为
Flyway
旨在准备数据库结构,而不是将其设置为已知状态。
因此,从概念上讲,
DbUnit
&
Arquillian持久性扩展
Flyway
做了两件完全不同的事情。 它们不是彼此的替代品

因此,使用flyway的代码:

@Before
public void setup() {
 ...
  flyway.clean();
  flyway.init();
  flyway.migrate();
}
是错误的,因为它应该在所有测试之前只运行一次。为此,您可以使用一些容器功能:

  • 如果使用EJB容器,则可以使用
    @Singleton
    +
    @Startup
    +
    @PostConstruct
    组合来启动flyway工具
  • 如果使用Spring容器,那么
    init method=“migrate”
    就可以了
  • 或者使用
    maven
    及其
    集成前测试
    阶段启动flyway工具
  • 顺便说一下:为了避免与DbUnit的xml数据集相关的维护工作,我个人建议使用这个工具。好的简单的解决方案

    编辑
    除此之外,在测试期间更改DB结构不是一个好的做法-您的问题也可能是由于Flyway和JPA使用不同的数据源(甚至指向同一个DB)造成的。您应该仔细检查是否不是自己创建数据源-只需为Flyway注入PersistenceUnit正在使用的同一个数据源。

    可以从发布奇怪的JPA问题开始,因为这些问题是意外的,可能指向不同的根本原因。另外,您是使用同一个EntityManager还是每次测试都获得一个新的EntityManager?一个错误是:org.postgresql.util.PSQLException:错误:重复键值违反唯一约束»abstractentity_pkey«Detail:key»(id)=(29420)«已存在序列/seq_count在数据库中具有正确的值。在我的测试套件中,我没有实体管理器(我正在使用jdbc连接重置它)。在我的应用程序中,我有@PersistenceContext(unitName=“mydatabasePU”)私有实体管理器em;我认为持久性上下文是每个usersession创建的。我不能在testsuite中重用上下文?我还可以使用@BeforeClass,它在类中的所有测试执行之前运行。只有一次。但是错误是一样的。所有重置工具都使用额外的jdbc连接。Java应用程序对数据库更改一无所知。我需要的是:我如何告诉应用程序数据库已经更改,所有内容都应该刷新/重置?不完全是这样,@BeforeClass是在每个测试类之前启动的-所以它仍然太多了。我不知道为什么,在测试过程中,您会改变整个数据库结构。这不是一个好的实践。我有多个UI测试类。每个UI测试类都应该从相同的干净情况开始,因为Test1正在创建一些与Test2冲突的数据。所以我想为每个类重置数据库。在一个testclass之后删除每个新数据是一个复杂的主题。一个testclass创建了很多数据库条目(多个表中有250-500个条目,有很多限制),我认为flyway sql转储重置是创建干净数据库的最简单方法。重新创建数据库不同于从all表中删除所有记录。请考虑后一种方法(DbStuts/AQuiLIN持久性扩展可能是有用的)。设置相同的数据源是有效的。资源(lookup=“mydatasource”)私有数据源数据源;setDataSoruce(数据源);谢谢你的帮助