【问题标题】:Testing django application with several legacy databases使用多个遗留数据库测试 django 应用程序
【发布时间】:2016-08-27 10:48:10
【问题描述】:

我有 5 个遗留数据库的 django 应用程序。几乎所有模型都设置了元属性managed=False。由于设置了managed=False,因此已使用选项managed=False 创建了每个模型的迁移。而且,由于 django 测试运行程序为每个模型选择现有迁移以在 test_databases 中创建测试表,因此它根本不会创建任何东西。 我尝试使用以下解决方法创建test.py 设置文件:

from web_services.settings.dev import *
from django.test.runner import DiscoverRunner


class UnManagedModelTestRunner(DiscoverRunner):

    def setup_test_environment(self, *args, **kwargs):
        from django.apps import apps
        self.unmanaged_models = [m for m in apps.get_models() if not m._meta.managed]
        for m in self.unmanaged_models:
            m._meta.managed = True
        super(UnManagedModelTestRunner, self).setup_test_environment(*args, **kwargs)

    def teardown_test_environment(self, *args, **kwargs):
        super(UnManagedModelTestRunner, self).teardown_test_environment(*args, **kwargs)
        # reset unmanaged models
        for m in self.unmanaged_models:
            m._meta.managed = False

TEST_RUNNER = 'web_services.settings.test.UnManagedModelTestRunner'

并运行python manage.py test --settings=web_services.settings.test。但是,它并没有帮助,因为无论如何 - 已经使用 managed=False 选项创建了现有迁移。只有在我在模型中注释掉 managed=False、删除旧迁移、创建新迁移(没有 managed=False 选项)之后,测试似乎才有效。

有了这个,我很迷茫 - 在我的案例(多个旧数据库)中编写测试实际上是一个好习惯吗?处理调整迁移的麻烦似乎是错误的。

【问题讨论】:

    标签: django django-testing django-tests


    【解决方案1】:

    这是我现在解决问题的方法。

    使用managed=False 选项创建的迁移如下所示:

    # migrations/0001_initial.py
    migrations.CreateModel(
                name='MyModel',
                fields=[
                    ('field_id', models.IntegerField(primary_key=True, serialize=False)),
                    ('slug', models.CharField(max_length=20, unique=True)),
                    ('name', models.CharField(max_length=64)),
                ],
                options={
                    'db_table': 'MyModel',
                    'managed': False,
                },
            ),
    

    需要注释掉'managed': False 以允许应用迁移。为了不弄乱实际的迁移,我创建了文件夹 test_migrations 并将我的迁移复制到那里,'managed': False 注释掉了:

    # test_migrations/0001_initial.py
    migrations.CreateModel(
                name='MyModel',
                fields=[
                    ('field_id', models.IntegerField(primary_key=True, serialize=False)),
                    ('slug', models.CharField(max_length=20, unique=True)),
                    ('name', models.CharField(max_length=64)),
                ],
                options={
                    'db_table': 'MyModel',
                    # 'managed': False,
                },
            ),
    

    然后我们需要在测试运行期间参考这些迁移。为此,我创建了设置文件 test.py 并在其中放置了必要的参考。像这样:

    from web_services.settings.dev import *
    
    
    MIGRATION_MODULES = {
        'myapp': 'web_services.apps.myapp.test_migrations',
    }
    

    并且在运行测试时,您需要参考该设置:

    python manage.py test --settings=web_services.settings.test

    【讨论】:

    • 谢谢。我已经为此苦恼了一段时间。你的是唯一有效的解决方案(在导入设置时遇到问题,但也有解决方法)
    • 虽然我并不特别喜欢维护单独的迁移副本,但这是迄今为止我发现的唯一可行的解​​决方案。
    • @AmirTugi 感谢您的回答。但是,如果您将if 'test' in sys.argv: MIGRATION_MODULES = { 'iop_bypass': 'test_migrations', } 这个放在settings.py 中,您可以以干净的方式改进此答案。好处是 1。您不需要新的 test_settings.py 2。您不需要使用额外的参数 3 运行测试。您不会遇到 linting 问题说你在 PEP8 中进行通配符导入
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 2010-11-04
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    相关资源
    最近更新 更多