我想有一个包含一些单元测试的python模块,我可以传递给hg bisect --command
。
单元测试正在测试django应用的一些功能,但我认为我不能使用hg bisect --command manage.py test mytestapp
,因为必须在settings.py中启用mytestapp
,并对设置进行编辑当hg bisect
更新工作目录时,.py将被破坏。
因此,我想知道以下是否是最好的方法:
import functools, os, sys, unittest
sys.path.append(path_to_myproject)
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
def with_test_db(func):
"""Decorator to setup and teardown test db."""
@functools.wraps
def wrapper(*args, **kwargs):
try:
# Set up temporary django db
func(*args, **kwargs)
finally:
# Tear down temporary django db
class TestCase(unittest.TestCase):
@with_test_db
def test(self):
# Do some tests using the temporary django db
self.fail('Mark this revision as bad.')
if '__main__' == __name__:
unittest.main()
如果您能提出建议,我将非常感激:
django.test.TestCase
,但不能编辑settings.py,如果没有; 答案 0 :(得分:10)
破解了。我现在有一个python文件完全独立于任何可以使用测试数据库运行单元测试的django应用程序:
#!/usr/bin/env python
"""Run a unit test and return result.
This can be used with `hg bisect`.
It is assumed that this file resides in the same dir as settings.py
"""
import os
from os.path import abspath, dirname
import sys
import unittest
# Set up django
project_dir = abspath(dirname(dirname(__file__)))
sys.path.insert(0, project_dir)
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
from django.db import connection
from django.test import TestCase
from django.test.utils import setup_test_environment, teardown_test_environment
from myproject import settings
from myproject.myapp.models import MyModel
class MyTestCase(TestCase):
def test_something(self):
# A failed assertion will make unittest.main() return non-zero
# which if used with `hg bisect` will mark the revision as bad
self.assertEqual(0, len(MyModel.objects.all())) # and so on
if '__main__' == __name__:
try:
setup_test_environment()
settings.DEBUG = False
verbosity = 0
old_database_name = settings.DATABASE_NAME
connection.creation.create_test_db(verbosity)
unittest.main()
finally:
connection.creation.destroy_test_db(old_database_name, verbosity)
teardown_test_environment()
答案 1 :(得分:5)
您必须使用内部Django TestCase才能这样做。
from django.test import TestCase
class TestCase(TestCase):
# before every call to setUp(), the db is automatically
# set back to the state is was after the first syncdb then
# all these fixture files will be loaded in the db
fixtures = ['mammals.json', 'birds']
# put whatever you want here, you don't need to call the
# super()
def setUp(self):
# Test definitions as before.
call_setup_methods()
def test(self):
# Do some tests using the temporary django db
self.fail('Mark this revision as bad.')
它与unittest完全兼容,因此您的代码不需要进行太多更改。
您可以详细了解django.test, fixtures,flush和loaddata命令。
如果您确实想使用装饰器来完成这项工作,您可以使用call_command
在您的python程序中使用任何django命令。例如:
from django.core.management import call_command
call_command('flush', 'myapp')
call_command('loaddata', 'myapp')