【问题标题】:Django unit test without creating test database every time I run每次运行时都没有创建测试数据库的 Django 单元测试
【发布时间】:2011-11-04 02:11:13
【问题描述】:

似乎“manage.py test”每次运行测试时都会创建测试数据库。有没有办法防止在我每次运行测试时创建测试数据库但只是截断数据(刷新)?

我的表大约有 40 个表(即使是单个应用程序,而不是整个项目),每次运行测试都让我感到恶心。

【问题讨论】:

    标签: django unit-testing


    【解决方案1】:

    从 Django 1.8 开始,您可以在调用 manage.py 时使用 --keepdb 标志

    Django 1.8 中的新功能:您可以防止测试数据库被 通过在测试命令中添加 --keepdb 标志 来销毁。这会 在运行之间保留测试数据库。如果数据库没有 存在,它将首先被创建。也将应用任何迁移 为了使其保持最新状态。 (https://docs.djangoproject.com/en/1.8/topics/testing/overview/#the-test-database)

    所以您的调用可能如下所示:

    python manage.py test --keepdb
    

    或者使用简写 -k 它可能看起来像这样:

    python manage.py test -k
    

    【讨论】:

    • 对于带有默认测试套件的现代 Django(1.8 或更高版本) - 这是最简单的。
    • 即使使用 keepdb,django 也坚持每次都运行迁移
    • @Matt 如果测试数据库不存在,它将在第一次运行时创建,然后为每次后续运行保留。在运行测试套件之前,任何未应用的迁移也将应用于测试数据库。 django-docs
    • @Matt 但是是的,每次运行测试时都会应用迁移(请参阅django-source 以供参考)。但是,以更高的详细模式 (python manage.py test -k --verbosity 2) 运行测试,您将看到迁移仅被检查,但如果之前已应用且在测试运行之间未更改,则不会重新应用。
    【解决方案2】:

    根据您的需要,您有几个选择:

    【讨论】:

      【解决方案3】:

      django-nose 支持复用数据库:

      https://github.com/django-nose/django-nose#enabling-database-reuse

      但是,请务必阅读 cmets:

      一个新的问题是,每当您的数据库架构发生变化时,您 下次运行测试时应该关闭该标志。这将提示 测试运行程序重新初始化测试数据库。

      此外,REUSE_DB 与离开的 TransactionTestCases 不兼容 数据库中的垃圾,所以一定要让你的 TransactionTestCases 卫生 (见下文)如果你想使用它。

      【讨论】:

        【解决方案4】:

        如果有更多的南迁移,以下解决方案也将减少数据库创建时间。在单元测试期间,运行 syncdb 而不是运行所有的南迁移会快得多。

        SOUTH_TESTS_MIGRATE = False # 禁用迁移并使用 syncdb 而是

        【讨论】:

          【解决方案5】:

          你也许可以试试test runner

          例子:

          首先,创建test_runners.py

          from django.test.runner import DiscoverRunner
          
          
          class NoDbTestRunner(DiscoverRunner):
          
              def setup_databases(self, **kwargs):
                  """ Override the database creation defined in parent class """
                  pass
          
              def teardown_databases(self, old_config, **kwargs):
                  """ Override the database teardown defined in parent class """
                  pass
          
          

          然后在settings.py中声明上面的runner

          TEST_RUNNER = 'api.tests.test_runners.NoDbTestRunner'
          

          【讨论】:

            【解决方案6】:

            我猜这不是最佳实践,但作为解决方法,我已经在应用程序的 management/commands 目录中创建了几个不同的测试程序。

            https://docs.djangoproject.com/en/1.7/howto/custom-management-commands/

            例如,我现在正在开发一个需要一些高级 Postgres 功能(不能使用 Sqlite)的应用程序,因此我没有在 test.py 中创建测试函数,而是在 myapp/management/commands/ 中创建了 test_process.py

            【讨论】:

              【解决方案7】:

              您可能希望pytest 作为测试运行程序。配置示例如下。

              示例pytest.ini 文件:

              [pytest]
              norecursedirs=
                  *.egg
                  .git
                  .tox
                  .env
                  _sass
                  build
                  dist
                  migrations
                  fabfile
                  .tox
              python_files =
                  test_*.py
                  tests.py
              DJANGO_SETTINGS_MODULE=settings.dev
              addopts=
                 --reuse-db
                 --nomigrations
                 --cov=your_app
                 --ignore=.tox
                 --ignore=fabfile
                 --ignore=scripts
                 --ignore=settings
                 --ignore=tmp
                 --cov-report=html
                 --cov-report=term
                 --cov-report=annotate
              

              示例runtests.py 文件:

              #!/usr/bin/env python
              import os
              import sys
              
              import pytest
              
              
              def main():
                  os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.dev")
                  return pytest.main()
              
              
              if __name__ == '__main__':
                  sys.exit(main())
              

              示例requirements.txt 文件:

              pytest==3.0.2
              pytest-django==2.9.1
              pytest-cov==2.2.1
              

              运行测试:

              ./runtests.py
              

              注意,该效果是通过reuse-dbnomigrations 指令实现的。

              【讨论】:

                【解决方案8】:

                当前版本的 Django 有一个 --keepdb 参数,您可以将其传递给测试,这样数据库就不会在每次运行时被破坏和重建。

                https://docs.djangoproject.com/en/3.0/ref/django-admin/#cmdoption-test-keepdb

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2020-11-17
                  • 1970-01-01
                  • 2023-01-11
                  • 2011-10-04
                  • 2011-08-20
                  • 2020-10-14
                  • 2014-06-28
                  • 2013-07-15
                  相关资源
                  最近更新 更多