是否有可能在没有设置数据库的情况下编写django单元测试?我想测试不需要db设置的业务逻辑.虽然设置db很快,但在某些情况下我真的不需要它.
moh*_*666 115
您可以继承DjangoTestSuiteRunner并覆盖要传递的setup_databases和teardown_databases方法.
创建一个新的设置文件,并将TEST_RUNNER设置为刚刚创建的新类.然后,当您运行测试时,请使用--settings标志指定新设置文件.
这是我做的:
创建一个类似于此的自定义测试套件运行器:
from django.test.simple import DjangoTestSuiteRunner
class NoDbTestRunner(DjangoTestSuiteRunner):
""" A test runner to test without database creation """
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
Run Code Online (Sandbox Code Playgroud)
创建自定义设置:
from mysite.settings import *
# Test runner with no database creation
TEST_RUNNER = 'mysite.scripts.testrunner.NoDbTestRunner'
Run Code Online (Sandbox Code Playgroud)
当您运行测试时,如下所示运行它,并将--settings标志设置为新的设置文件:
python manage.py test myapp --settings='no_db_settings'
Run Code Online (Sandbox Code Playgroud)
更新:2018年4月
由于Django的1.8,该模块被移动到.django.test.simple.DjangoTestSuiteRunner
'django.test.runner.DiscoverRunner'
有关更多信息,请查看有关自定义测试运行器的官方doc部分
小智 58
通常,应用程序中的测试可以分为两类
Django支持单元测试和集成测试.
单元测试,不需要设置和拆除数据库,这些我们应该继承SimpleTestCase.
from django.test import SimpleTestCase
class ExampleUnitTest(SimpleTestCase):
def test_something_works(self):
self.assertTrue(True)
Run Code Online (Sandbox Code Playgroud)
对于集成测试用例,继承自TestCase的测试用例继承自TransactionTestCase,它将在运行每个测试之前设置和拆除数据库.
from django.test import TestCase
class ExampleIntegrationTest(TestCase):
def test_something_works(self):
#do something with database
self.assertTrue(True)
Run Code Online (Sandbox Code Playgroud)
此策略将确保仅为访问数据库的测试用例创建和销毁数据库,因此测试将更有效
the*_*max 28
从 django.test.simple
warnings.warn(
"The django.test.simple module and DjangoTestSuiteRunner are deprecated; "
"use django.test.runner.DiscoverRunner instead.",
RemovedInDjango18Warning)
Run Code Online (Sandbox Code Playgroud)
所以覆盖DiscoverRunner
而不是DjangoTestSuiteRunner
.
from django.test.runner import DiscoverRunner
class NoDbTestRunner(DiscoverRunner):
""" A test runner to test without database creation/deletion """
def setup_databases(self, **kwargs):
pass
def teardown_databases(self, old_config, **kwargs):
pass
Run Code Online (Sandbox Code Playgroud)
使用那样:
python manage.py test app --testrunner=app.filename.NoDbTestRunner
Run Code Online (Sandbox Code Playgroud)
我选择继承django.test.runner.DiscoverRunner
并对该run_tests
方法进行了一些补充.
我的第一个添加检查是否需要设置数据库,并允许在需要数据库时启动正常setup_databases
功能.teardown_databases
如果setup_databases
允许该方法运行,我的第二次添加允许正常运行.
我的代码假定任何继承的TestCase django.test.TransactionTestCase
(因此django.test.TestCase
)都需要设置数据库.我做了这个假设,因为Django文档说:
如果您需要任何其他更复杂和重量级的Django特定功能,如...测试或使用ORM ...那么您应该使用TransactionTestCase或TestCase.
https://docs.djangoproject.com/en/1.6/topics/testing/tools/#django.test.SimpleTestCase
from django.test import TransactionTestCase
from django.test.runner import DiscoverRunner
class MyDiscoverRunner(DiscoverRunner):
def run_tests(self, test_labels, extra_tests=None, **kwargs):
"""
Run the unit tests for all the test labels in the provided list.
Test labels should be dotted Python paths to test modules, test
classes, or test methods.
A list of 'extra' tests may also be provided; these tests
will be added to the test suite.
If any of the tests in the test suite inherit from
``django.test.TransactionTestCase``, databases will be setup.
Otherwise, databases will not be set up.
Returns the number of tests that failed.
"""
self.setup_test_environment()
suite = self.build_suite(test_labels, extra_tests)
# ----------------- First Addition --------------
need_databases = any(isinstance(test_case, TransactionTestCase)
for test_case in suite)
old_config = None
if need_databases:
# --------------- End First Addition ------------
old_config = self.setup_databases()
result = self.run_suite(suite)
# ----------------- Second Addition -------------
if need_databases:
# --------------- End Second Addition -----------
self.teardown_databases(old_config)
self.teardown_test_environment()
return self.suite_result(suite, result)
Run Code Online (Sandbox Code Playgroud)
最后,我将以下行添加到项目的settings.py文件中.
TEST_RUNNER = 'mysite.scripts.settings.MyDiscoverRunner'
Run Code Online (Sandbox Code Playgroud)
现在,当只运行非数据库相关的测试时,我的测试套件运行速度提高了一个数量级!:)
更新:另请参阅此答案以了解如何使用第三方工具pytest
.
@Cesar是对的.意外运行后./manage.py test --settings=no_db_settings
,未指定应用程序名称,我的开发数据库被清除.
为了更安全的方式,使用相同的NoDbTestRunner
,但结合以下内容mysite/no_db_settings.py
:
from mysite.settings import *
# Test runner with no database creation
TEST_RUNNER = 'mysite.scripts.testrunner.NoDbTestRunner'
# Use an alternative database as a safeguard against accidents
DATABASES['default']['NAME'] = '_test_mysite_db'
Run Code Online (Sandbox Code Playgroud)
您需要创建一个_test_mysite_db
使用外部数据库工具调用的数据库.然后运行以下命令以创建相应的表:
./manage.py syncdb --settings=mysite.no_db_settings
Run Code Online (Sandbox Code Playgroud)
如果您使用的是South,请运行以下命令:
./manage.py migrate --settings=mysite.no_db_settings
Run Code Online (Sandbox Code Playgroud)
好!
您现在可以通过以下方式快速(和安全)地运行单元测试:
./manage.py test myapp --settings=mysite.no_db_settings
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
33447 次 |
最近记录: |