Java 使用arquilian进行测试时,何时构建DB结构?

Java 使用arquilian进行测试时,何时构建DB结构?,java,jboss-arquillian,Java,Jboss Arquillian,我从集成测试和Arquilian开始。我对这个工具很满意。 我几乎什么都准备好了,除了一件事: 当然,在整个测试套件中,我的数据库结构是稳定的,因此,为了减少测试运行所需的时间,我希望尽可能少地构建数据库,并让每个测试填充数据库,对其进行处理和清理 我认为在测试套件的开头构建数据库并让所有测试填充/删除数据库可能有点风险:如果一个测试没有很好地清理,我可能会得到不可复制的测试 但是,在每个测试类中构建它可能是一种很好的方法,在有问题的测试中,它会更容易发现,因为范围更小 我尝试使用@Before

我从集成测试和Arquilian开始。我对这个工具很满意。 我几乎什么都准备好了,除了一件事:

当然,在整个测试套件中,我的数据库结构是稳定的,因此,为了减少测试运行所需的时间,我希望尽可能少地构建数据库,并让每个测试填充数据库,对其进行处理和清理

我认为在测试套件的开头构建数据库并让所有测试填充/删除数据库可能有点风险:如果一个测试没有很好地清理,我可能会得到不可复制的测试

但是,在每个测试类中构建它可能是一种很好的方法,在有问题的测试中,它会更容易发现,因为范围更小

我尝试使用@BeforeClass和@AfterClass来实现这一点,但它们是在客户端上执行的,也是静态的,因此我没有准备好用于连接数据库的资源


我在每次测试之前创建DB结构的方法正确吗?arquilian生命周期的哪个阶段可以用来构建数据库?

您不必自己动手,至少如果您在项目中使用JPA 2.1。考虑下面的测试类:

@RunWith(Arquillian.class)
public class MyTest {

    @Deployment
    public static WebArchive createDeployment() throws Exception {
        return ShrinkWrap.create(WebArchive.class)
            .addAsResource("META-INF/init-schema.sql")  // create table ...
            .addAsResource("META-INF/testdata.sql")  // insert into ...
            .addAsResource("META-INF/drop-schema.sql") // drop table ...
            .addAsResource("META-INF/persistence.xml");
            // and maybe more ...
    }

}
调用
createDeployment()
方法来创建WAR文件,该文件将部署到应用服务器

您的
persistence.xml
应该引用以下SQL脚本:

[...]
<persistence-unit [...]>
    <properties>
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
        <property name="javax.persistence.schema-generation.create-source" value="script" />
        <property name="javax.persistence.schema-generation.create-script-source" value="META-INF/init-schema.sql" />
        <property name="javax.persistence.schema-generation.drop-source" value="script" />
        <property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/drop-schema.sql" />
        <property name="javax.persistence.sql-load-script-source" value="META-INF/testdata.sql" />
    </properties>
</persistence-unit>

使用Arqullian的事务扩展,它工作得非常好()。测试完成后,您在事务中创建的数据将被删除


唯一的问题是数据库中的数据可能会影响您的测试。解决方案是针对空数据库进行测试。它可以是嵌入式的、真实的或上面描述的方法。但是扩展可以正确地管理所有事务管理,您不必关心任何事情。

这是个好消息!我会尽快(可能是星期一)告诉你!谢谢我想在测试中使用的脚本是用于在数据库中部署的脚本,它使用$$作为分隔符。我收到错误消息:无法执行JPA架构生成创建命令[DELIMITER$$],可能是因为换行。看看我的表。它将多个文件合并到一个SQL文件中,并处理$$分隔符。使用
addAsResource(sqlAsset,“testdata.sql”)
public class MyTest {
    [...]

    private @Inject EntityManager entityManager

    @Test @InSequence(0)
    public void shouldHaveFoo() {
        Foo foo = entityManager.find(Foo.class, Long.valueOf(1));
        assertNotNull(foo);
    }

    @Test @InSequence(1)
    public void shouldHaveBar() {
        Bar bar = entityManager.find(Bar.class, Long.valueOf(99));
        assertNotNull(bar);
    }
}