首页 > 解决方案 > 跳过为只读、外部管理、高安全性、大型数据库创建 Django 测试数据库

问题描述

在 Django 测试期间,我们需要为众多外部数据源之一使用真实数据:

我们了解缺点:这违反了测试纯度并引入了潜在的安全风险。我们愿意在这两个方面做出妥协,以使我们度过接下来的几个月,届时我们将逐步淘汰这个有问题的数据源。

在这种情况下,我需要 Django 了解我不希望它为此源建立一个测试数据库,而只使用实际源,这样我们就可以运行一些快速检查并离开。

在充分理解和接受风险和建议的情况下,实现这一目标的最简单方法是什么?

标签: djangodatabasetestingorm

解决方案


对我们来说,解决方案是自定义测试运行器。

Django 的高级测试主题文档的帮助下,我们像这样覆盖了默认值DiscoverRunner

from django.test.runner import DiscoverRunner


def should_create_db(db_name):
    # analyse db_name, a key from DATABASES, to determine whether a test
    # database should be created
    return db_name != 'messy_legacy_database'


class CustomTestRunner(DiscoverRunner):
    
    # override method from superclass to selectively skip database setup
    def setup_databases(self, **kwargs):
        # 'aliases' is a set of unique keys from settings DATABASES dictionary
        aliases = kwargs.get('aliases')
        filtered = set([i for i in aliases if should_create_db(i)])
        kwargs['aliases'] = filtered
        # 'aliases' now contains only keys which trigger test database creation
        return super().setup_databases(**kwargs)

    # there was no need to override teardown_databases()

接下来我们更新settings.py以使用我们的覆盖而不是默认运行器:

TEST_RUNNER = 'path.to.CustomTestRunner'

最后我们告诉我们的测试类它可以使用哪些数据库:

from django.test import TestCase


class OurTest(TestCase):
    databases = [
        'default',
        'messy_legacy_database',
    ]

    def test_messy_legacy_database(self):
        # go nuts on your messy legacy database testing calls
        pass

通过这种方式,我们的测试现在跳过了为我们凌乱的遗留数据库创建测试数据库,并且我们测试的逻辑从实际数据源中提取数据,允许我们实施快速检查以确保这些代码路径有效。


推荐阅读