2013-02-21 33 views
1

由于各种原因,我们使用鼻子功能测试编写我们的测试套件。如何清理django-nose测试功能中的数据库更改?

当为我们的Django应用程序运行测试套件时,我们希望避免泄漏任何数据(如django.test.TestCase),因为这会导致耦合并难以诊断故障。

解决这个问题的最明显的方法是装饰器,我们可以将测试包裹起来,然后我们就可以将其清理干净,但如果不同的解决方案能够获得我们想要的结果,我就不会结婚。

我们在PostgreSQL上运行,所以Postgres特定的解决方案将会很好。

+1

django在每次测试运行时自动关闭数据库,这会创建一个独立的测试环境 – dm03514 2013-02-21 17:24:08

+0

@ dm03514经过一番探索之后,我意识到这是发生在django-nose测试功能上的,而不是更一般的情况我最初是用这个问题起草的。 – 2013-02-21 17:27:31

回答

1

我花了一点时间看这个今天,并拿出了以下装饰:

from functools import wraps 

from django.db import transaction 
from mock import patch 

def rollback_db_changes(func): 
    """Decorate a function so that it will be rolled back once completed.""" 
    @wraps(func) 
    @transaction.commit_manually 
    def new_f(*args, **kwargs): 
     def fake_commit(using=None): 
      # Don't properly commit the transaction, so we can roll it back 
      transaction.set_clean(using) 
     patcher = patch('django.db.transaction.commit', fake_commit) 
     patcher.start() 
     try: 
      return func(*args, **kwargs) 
     finally: 
      patcher.stop() 
      transaction.rollback() 
    return new_f 

我们进行打补丁,使Django的测试客户端不会不关闭交易我们能够回滚。这允许通过以下测试:

from django.contrib.auth.models import User 

@rollback_db_changes 
def test_allowed_access(): 
    user = User.objects.create(username='test_user') 
    eq_(1, User.objects.count()) 


@rollback_db_changes 
def test_allowed_access_2(): 
    user = User.objects.create(username='test_user') 
    eq_(1, User.objects.count()) 

以前第二次测试运行无法创建具有重复的用户名的用户。

+0

嗯,严格来说,那些测试失败了,因为我们的代码库中的其他地方没有清理他们的混乱。但你明白了。 – 2013-02-22 10:25:56

相关问题