我想创建单元测试,涵盖在 Play 框架 2.1.0 中使用关系数据库的代码。这有很多可能性,并且都会导致问题:
在内存 H2 数据库上进行测试
Play 框架文档建议在 H2 内存数据库上运行单元测试,即使用于开发和生产的主数据库使用其他软件(即 MySQL):
app = Helpers.fakeApplication(Helpers.inMemoryDatabase());
我的应用程序不使用存储过程等复杂的 RDBMS 功能,并且大多数数据库访问案例都是 ebean 调用,因此它应该与 MySQL 和 H2 兼容。
但是,evolutions 中的建表语句使用 MySQL 特有的功能,例如指定
ENGINE = InnoDB
,
DEFAULT CHARACTER SET = utf8
等。我担心我是否会删除
CREATE TABLE
的这些专有部分, MySQL 将使用一些我无法控制且取决于版本的默认设置,因此要测试和开发应用程序主 MySQL 配置必须修改。
有人使用过这种方法(使进化与 MySQL 和 H2 兼容)吗?
如何处理它的其他想法:
create table
中的其他 MySQL 内容的某种方法(MySQL 兼容模式不起作用,即使在 default character set
上它仍然会提示)。我不知道怎么做。 在与主数据库相同的数据库驱动程序上进行测试
H2 内存数据库的唯一优势是速度快,并且在相同的数据库驱动程序上进行测试可能比开发/生产数据库更好,因为它更接近真实环境。
如何在 Play 框架中正确完成?
试过:
Map<String, String> settings = new HashMap<String, String>();
settings.put("db.default.url", "jdbc:mysql://localhost/sometestdatabase");
settings.put("db.default.jndiName", "DefaultDS");
app = Helpers.fakeApplication(settings);
看起来进化在这里起作用,但是在每次测试之前最好如何清理数据库?通过创建截断每个表的自定义代码?如果它会删除表,那么进化将在下一次测试之前再次运行,或者每个
play test
应用一次命令?或每
Helpers.fakeApplication()
一次调用?
这里有哪些最佳实践?听说 dbunit ,是否可以在没有太多痛苦和怪癖的情况下集成它?
请您参考如下方法:
首先,我建议您使用相同的 RDBMS 进行测试和生产,因为它可以避免一些难以发现的错误。
关于在每次测试之间清理数据库的需要,您可以使用 Ebean DdlGenerator
生成脚本以创建干净的数据库和 JUnit 的 @Before
注释以在每次测试之前自动执行这些脚本。
使用 DdlGenerator
可以这样做:
EbeanServer server = Ebean.getServer(serverName);
ServerConfig config = new ServerConfig();
DdlGenerator ddl = new DdlGenerator((SpiEbeanServer) server, new MySqlPlatform(), config);
这段代码可以放在一个基类中,你可以继承你的测试(或者在一个自定义的
Runner
中,你可以使用
@RunWith
注解)。
它还可以让您轻松自动化
FakeApplication
创建,避免一些样板代码。
一些可能有用的链接: