python - 如何清理在 django-nose 测试函数中所做的数据库更改?

标签 python django unit-testing postgresql django-nose

出于各种原因,我们使用 Nose 功能测试编写测试套件。

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

解决这个问题的最明显的方法是一个装饰器,我们可以将我们想要在之后清理的测试包装起来,但如果不同的解决方案可以得到我们想要的东西,我不会嫁给它。

我们在 PostgreSQL 上运行,因此特定于 Postgres 的解决方案会很好。

最佳答案

我今天花了一些时间研究这个,并提出了以下装饰器:

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())

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

关于python - 如何清理在 django-nose 测试函数中所做的数据库更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15008149/

相关文章:

python - scikit-learn 和 mllib 在预测 python 上的区别

python - 在 Common Lisp 中管理依赖关系

python - 带有 subprocess.run() 脚本的 Oarsub 作业

python - 我可以在 GAE 上使用 django.contrib.gis 吗?

php - Symfony2 PHPUnit 时钟模拟不起作用

python - float 相乘在 Numpy 和 R 中给出不同的结果

javascript - 使用 Django 和 Backbone 进行渐进增强 - 如何将两者集成?

python - 已删除 InDjango19 警告 : Model doesn't declare an explicit app_label

c# - 基本 RX TestScheduler 时序

python - 在不同条件下运行一组标准的nosetests函数