我整理了一个试图自动管理数据库的unit testing plugin for Symfony 1.4,类似于Django测试框架的方式(在测试之间销毁和重建数据库)。
在第一次测试运行之前销毁和重建数据库是有意义的,因为架构可能在开发过程中发生了变化,并且让开发人员让他的测试数据库与他的模型手动同步也是非常可悲的。
然而,在第一次测试运行之后,我发现删除所有数据通常更快,这将是一个相当简单的任务,除了外键问题,这需要删除数据正确的顺序。
对于MySQL,这不是问题;简单地SET FOREIGN_KEY_CHECKS = 0
,你可以破坏你心灵内容的参照完整性(当然,到SET FOREIGN_KEY_CHECKS = 1
时,但是在这种情况下,没有数据,所以MySQL没有抱怨)。
但只有测试数据库使用MySQL时,这才有效。对于任何其他DBMS(尤其是Sqlite),这将失败。
Doctrine 1.2是否提供了删除每个表中所有数据的方法,或者是否有“跟随”关系的方法(即,确定哪些表具有外键并首先从中删除)?
答案 0 :(得分:2)
我会使用Doctrine DBAL并首先找到外键。请查看Doctrine的DBAL文档,其中包含Schema-Manager及其相关API documentation以及ForeignKeyConstraint中提供的方法。
编辑:对于doctrine 1.2,似乎有类似的方法来检索记录here的外键。
查找所有外键约束,并根据约束让代码决定,以哪种顺序删除数据。
答案 1 :(得分:0)
Doctrine_Data->purge()
利用Doctrine_Connection_UnitOfWork->buildFlushTree()
来完成我想要完成的任务。
有点理智,看看Doctrine_Data_Import->doImport()
(即symfony doctrine:data-load
)已经提供了我正在尝试重塑的功能......我怎么会错过那个? :P
答案 2 :(得分:0)
采用另一种方法(尽管不是很简单)是使用交易。
在测试开始时启动事务,然后在测试完成后发出回滚。数据库将删除测试期间创建的所有数据。
然而,必须注意确保实际依赖于交易的经过测试的代码继续有效。
这是Django's test framework的工作方式:
class TestCase(TransactionTestCase): """ Does basically the same as TransactionTestCase, but surrounds every test with a transaction, monkey-patches the real transaction management routines to do nothing, and rollsback the test transaction at the end of the test. You have to use TransactionTestCase, if you need transaction management inside a test. """