如何使用 dbUnit 将数据库恢复到初始状态?
Posted
技术标签:
【中文标题】如何使用 dbUnit 将数据库恢复到初始状态?【英文标题】:How to revert the database back to the initial state using dbUnit? 【发布时间】:2011-04-18 08:09:56 【问题描述】:我是自动化测试和 dbUnit 的新手。所以我很感激你的建议。
我将创建一个测试套件,它将按以下方式运行:
创建内存 H2 数据库 运行 DDL 脚本来创建表 运行 dbUnit 以插入所有测试都将使用的初始数据(我们称之为 STATE0)。 运行测试直到那里对我来说看起来不错,但我不明白,我如何在测试运行后将数据库恢复到 STATE0 并更改数据?
我可以用 dbUnit 做吗? 还是用别的东西? 我应该在每次测试之前重新创建数据库吗?
在测试中简单的不提交事务不适合我,因为测试最终会运行多个事务,可能不止一个数据库连接。
【问题讨论】:
【参考方案1】:如果您正确编写@BeforeClass
、@Before
和@After
方法,DBUnit 可以自动完成四个工作。例如。在我们的项目中,使用 Derby,一个这样的测试用例看起来像
public class MyTest
protected static IDataSet getDataSet() throws Exception
URL url = MyTest.class.getClassLoader().getResource("MyDataSet.xml");
return new XmlDataSet(new FileInputStream(url.getPath()));
private static JdbcDatabaseTester databaseTester;
@BeforeClass
public static void setUpClass() throws Exception
// Init test environment, session etc.
databaseTester = new JdbcDatabaseTester(
"org.apache.derby.jdbc.ClientDriver",
"jdbc:derby://localhost:1527/myschema",
"username", "password");
databaseTester.setDataSet(getDataSet());
@AfterClass
public static void tearDownClass()
// Close session etc.
@Before
public void setUp() throws Exception
databaseTester.onSetup();
@After
public void tearDown() throws Exception
databaseTester.onTearDown();
@Test
public void test() throws Exception ...
此代码在每次测试后将 DB 模式(的子集)恢复为 MyDataSet.xml
定义的状态。 (请注意,正如@Pascal 评论的那样,重置可能并不总是完整的 - 如果测试修改了不在数据集中的表,它不会受到@Before
/ @After
方法的影响。)
【讨论】:
这真的“重置”了数据库吗?我的意思是,如果我的测试在表FOO
中插入了一些数据并且如果MyDataSet.xml
不包括FOO
,FOO
将不会被“重置”,对吧?
@Pascal,你可能是对的。作为人类,如果我正在运行涉及表 FOO
的测试,始终建议仔细检查,该表实际上包含在数据集中。
éter 我同意这一点。只是我内心的挑剔者并没有完全相信最后一句话的措辞:)+1。
@Pascal,在我们的职业中,提前挑剔几乎总是比事后道歉要好:-)所以感谢您的评论,我更新了我的答案以使其(希望)更清晰。
【参考方案2】:
要将数据库初始化为初始数据集,只需在测试用例中实现这些方法即可:
@Override
protected DatabaseOperation getSetUpOperation() throws Exception
return DatabaseOperation.CLEAN_INSERT; // by default (will do DELETE_ALL + INSERT)
@Override
protected DatabaseOperation getTearDownOperation() throws Exception
return DatabaseOperation.NONE; // by default
如果您的某些测试在空表中插入行(例如,未在初始数据集中定义),您可能会有外键约束。
只需在您的数据集中添加这个空表,没有任何行:
<mydb_mypopulatedtable id="1" name="toto" alias="funky"/>
<mydb_mypopulatedtable id="2" name="titi" alias="groovy"/>
<mydb_mypopulatedtable id="3" name="tutu" alias="creepy"/>
<mydb_myemptytable />
这里,myemptytable 有一个指向 mypopulatedtable 的外键。如果未定义 myemptytable,DBUnit 将尝试删除 mypopulatedtable,但由于约束而失败。如果已定义,DBUnit 将删除之前的 myemptytable 行。
【讨论】:
一直在寻找这个!以上是关于如何使用 dbUnit 将数据库恢复到初始状态?的主要内容,如果未能解决你的问题,请参考以下文章