2006-10-10

rake test:units在SQL和Ruby DSL两种schema模式下的差异

关键字: rails test schema foreignkey 外键 测试
sql方式,会复制development数据库中的外键。相反,在schema模式下的外键是被完全忽略的,即使开发数据库里有,也不会复制到test数据库里。

而test:units执行的时候是根据environment.rb里的config.active_record.schema_format = sql设置(注释掉时为ruby dsl模式)来判断用哪种模式的。通过使用rake test:units --trace我们可以看见两者的差别:(忽略invoke,只看execute)

ruby dsl模式的schema下执行的task:
** Invoke test:units (first_time)     
** Invoke db:test:prepare (first_time)
** Invoke environment (first_time)    
** Execute environment                
** Execute db:test:prepare            
** Invoke db:test:clone (first_time)  
** Invoke db:schema:dump (first_time) 
** Invoke environment                 
** Execute db:schema:dump             
** Execute db:test:clone              
** Invoke db:schema:load (first_time) 
** Invoke environment                 
** Execute db:schema:load             
** Execute test:units               
...

sql模式的schema下执行的task: 
** Invoke test:units (first_time)            
** Invoke db:test:prepare (first_time)       
** Invoke environment (first_time)           
** Execute environment                       
** Execute db:test:prepare                   
** Invoke db:test:clone_structure (first_time)
** Invoke db:structure:dump (first_time)     
** Invoke environment                        
** Execute db:structure:dump                 
** Invoke db:test:purge (first_time)         
** Invoke environment                        
** Execute db:test:purge                     
** Execute db:test:clone_structure           
** Execute test:units                        

具体的task内部代码就不展开讨论了,关键差别是sql模式知道有外键存在,所以多了一个db:test:purge直接删整个数据库而不管表顺序一一删除的操作。而schema模式假设没有外键,只是简单用load。load这个操作就是删一个再建一个的,这某种程度上是ruby dsl风格的schema的限制所致(必须顺序执行,不能事先检查外键依赖关系)。

所以解决办法就是:先purge掉test数据库,然后设好config.active_record.schema_format要外键的用sql格式,不要外键用ruby dsl格式(但是has_many之类关联设置后面最好设一下:dependent参数)。然后直接用test:units,不用事先自己建立test表结构。
评论
发表评论

您还没有登录,请登录后发表评论

cookoo
搜索本博客
我的相册
1e04c0dc-42a1-45a4-b392-aa82faafa7ea-thumb
20059805856241
共 10 张
存档
最新评论
评论排行榜