blob: 22e9fe6af51123de6d038c41fec60dc1f5bf2438 [file] [log] [blame]
"""
Tests for django test runner
"""
from __future__ import absolute_import
import StringIO
from optparse import make_option
import warnings
from django.core.exceptions import ImproperlyConfigured
from django.core.management import call_command
from django import db
from django.test import simple
from django.test.simple import DjangoTestSuiteRunner, get_tests
from django.test.testcases import connections_support_transactions
from django.test.utils import get_warnings_state, restore_warnings_state
from django.utils import unittest
from django.utils.importlib import import_module
from ..admin_scripts.tests import AdminScriptTestCase
TEST_APP_OK = 'regressiontests.test_runner.valid_app.models'
TEST_APP_ERROR = 'regressiontests.test_runner.invalid_app.models'
class DjangoTestRunnerTests(unittest.TestCase):
def setUp(self):
self._warnings_state = get_warnings_state()
warnings.filterwarnings('ignore', category=DeprecationWarning,
module='django.test.simple')
def tearDown(self):
restore_warnings_state(self._warnings_state)
def test_failfast(self):
class MockTestOne(unittest.TestCase):
def runTest(self):
assert False
class MockTestTwo(unittest.TestCase):
def runTest(self):
assert False
suite = unittest.TestSuite([MockTestOne(), MockTestTwo()])
mock_stream = StringIO.StringIO()
dtr = simple.DjangoTestRunner(verbosity=0, failfast=False, stream=mock_stream)
result = dtr.run(suite)
self.assertEqual(2, result.testsRun)
self.assertEqual(2, len(result.failures))
dtr = simple.DjangoTestRunner(verbosity=0, failfast=True, stream=mock_stream)
result = dtr.run(suite)
self.assertEqual(1, result.testsRun)
self.assertEqual(1, len(result.failures))
class DependencyOrderingTests(unittest.TestCase):
def test_simple_dependencies(self):
raw = [
('s1', ('s1_db', ['alpha'])),
('s2', ('s2_db', ['bravo'])),
('s3', ('s3_db', ['charlie'])),
]
dependencies = {
'alpha': ['charlie'],
'bravo': ['charlie'],
}
ordered = simple.dependency_ordered(raw, dependencies=dependencies)
ordered_sigs = [sig for sig,value in ordered]
self.assertIn('s1', ordered_sigs)
self.assertIn('s2', ordered_sigs)
self.assertIn('s3', ordered_sigs)
self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1'))
self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2'))
def test_chained_dependencies(self):
raw = [
('s1', ('s1_db', ['alpha'])),
('s2', ('s2_db', ['bravo'])),
('s3', ('s3_db', ['charlie'])),
]
dependencies = {
'alpha': ['bravo'],
'bravo': ['charlie'],
}
ordered = simple.dependency_ordered(raw, dependencies=dependencies)
ordered_sigs = [sig for sig,value in ordered]
self.assertIn('s1', ordered_sigs)
self.assertIn('s2', ordered_sigs)
self.assertIn('s3', ordered_sigs)
# Explicit dependencies
self.assertLess(ordered_sigs.index('s2'), ordered_sigs.index('s1'))
self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2'))
# Implied dependencies
self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1'))
def test_multiple_dependencies(self):
raw = [
('s1', ('s1_db', ['alpha'])),
('s2', ('s2_db', ['bravo'])),
('s3', ('s3_db', ['charlie'])),
('s4', ('s4_db', ['delta'])),
]
dependencies = {
'alpha': ['bravo','delta'],
'bravo': ['charlie'],
'delta': ['charlie'],
}
ordered = simple.dependency_ordered(raw, dependencies=dependencies)
ordered_sigs = [sig for sig,aliases in ordered]
self.assertIn('s1', ordered_sigs)
self.assertIn('s2', ordered_sigs)
self.assertIn('s3', ordered_sigs)
self.assertIn('s4', ordered_sigs)
# Explicit dependencies
self.assertLess(ordered_sigs.index('s2'), ordered_sigs.index('s1'))
self.assertLess(ordered_sigs.index('s4'), ordered_sigs.index('s1'))
self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2'))
self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s4'))
# Implicit dependencies
self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1'))
def test_circular_dependencies(self):
raw = [
('s1', ('s1_db', ['alpha'])),
('s2', ('s2_db', ['bravo'])),
]
dependencies = {
'bravo': ['alpha'],
'alpha': ['bravo'],
}
self.assertRaises(ImproperlyConfigured, simple.dependency_ordered, raw, dependencies=dependencies)
class MockTestRunner(object):
invoked = False
def __init__(self, *args, **kwargs):
pass
def run_tests(self, test_labels, extra_tests=None, **kwargs):
MockTestRunner.invoked = True
class ManageCommandTests(unittest.TestCase):
def test_custom_test_runner(self):
call_command('test', 'sites',
testrunner='regressiontests.test_runner.tests.MockTestRunner')
self.assertTrue(MockTestRunner.invoked,
"The custom test runner has not been invoked")
class CustomOptionsTestRunner(simple.DjangoTestSuiteRunner):
option_list = (
make_option('--option_a','-a', action='store', dest='option_a', default='1'),
make_option('--option_b','-b', action='store', dest='option_b', default='2'),
make_option('--option_c','-c', action='store', dest='option_c', default='3'),
)
def __init__(self, verbosity=1, interactive=True, failfast=True, option_a=None, option_b=None, option_c=None, **kwargs):
super(CustomOptionsTestRunner, self).__init__(verbosity=verbosity, interactive=interactive,
failfast=failfast)
self.option_a = option_a
self.option_b = option_b
self.option_c = option_c
def run_tests(self, test_labels, extra_tests=None, **kwargs):
print "%s:%s:%s" % (self.option_a, self.option_b, self.option_c)
class CustomTestRunnerOptionsTests(AdminScriptTestCase):
def setUp(self):
settings = {
'TEST_RUNNER': '\'regressiontests.test_runner.tests.CustomOptionsTestRunner\'',
}
self.write_settings('settings.py', sdict=settings)
def tearDown(self):
self.remove_settings('settings.py')
def test_default_options(self):
args = ['test', '--settings=regressiontests.settings']
out, err = self.run_django_admin(args)
self.assertNoOutput(err)
self.assertOutput(out, '1:2:3')
def test_default_and_given_options(self):
args = ['test', '--settings=regressiontests.settings', '--option_b=foo']
out, err = self.run_django_admin(args)
self.assertNoOutput(err)
self.assertOutput(out, '1:foo:3')
def test_option_name_and_value_separated(self):
args = ['test', '--settings=regressiontests.settings', '--option_b', 'foo']
out, err = self.run_django_admin(args)
self.assertNoOutput(err)
self.assertOutput(out, '1:foo:3')
def test_all_options_given(self):
args = ['test', '--settings=regressiontests.settings', '--option_a=bar', '--option_b=foo', '--option_c=31337']
out, err = self.run_django_admin(args)
self.assertNoOutput(err)
self.assertOutput(out, 'bar:foo:31337')
class Ticket16885RegressionTests(unittest.TestCase):
def test_ticket_16885(self):
"""Features are also confirmed on mirrored databases."""
old_db_connections = db.connections
try:
db.connections = db.ConnectionHandler({
'default': {
'ENGINE': 'django.db.backends.sqlite3',
},
'slave': {
'ENGINE': 'django.db.backends.sqlite3',
'TEST_MIRROR': 'default',
},
})
slave = db.connections['slave']
self.assertEqual(slave.features.supports_transactions, None)
DjangoTestSuiteRunner(verbosity=0).setup_databases()
self.assertNotEqual(slave.features.supports_transactions, None)
finally:
db.connections = old_db_connections
class Ticket17477RegressionTests(AdminScriptTestCase):
def setUp(self):
self.write_settings('settings.py')
def tearDown(self):
self.remove_settings('settings.py')
def test_ticket_17477(self):
"""'manage.py help test' works after r16352."""
args = ['help', 'test']
out, err = self.run_manage(args)
self.assertNoOutput(err)
class ModulesTestsPackages(unittest.TestCase):
def test_get_tests(self):
"Check that the get_tests helper function can find tests in a directory"
module = import_module(TEST_APP_OK)
tests = get_tests(module)
self.assertIsInstance(tests, type(module))
def test_import_error(self):
"Test for #12658 - Tests with ImportError's shouldn't fail silently"
module = import_module(TEST_APP_ERROR)
self.assertRaises(ImportError, get_tests, module)
class Sqlite3InMemoryTestDbs(unittest.TestCase):
@unittest.skipUnless(all(db.connections[conn].vendor == 'sqlite' for conn in db.connections),
"This is a sqlite-specific issue")
def test_transaction_support(self):
"""Ticket #16329: sqlite3 in-memory test databases"""
old_db_connections = db.connections
for option in ('NAME', 'TEST_NAME'):
try:
db.connections = db.ConnectionHandler({
'default': {
'ENGINE': 'django.db.backends.sqlite3',
option: ':memory:',
},
'other': {
'ENGINE': 'django.db.backends.sqlite3',
option: ':memory:',
},
})
other = db.connections['other']
self.assertIsNone(other.features.supports_transactions)
DjangoTestSuiteRunner(verbosity=0).setup_databases()
msg = "DATABASES setting '%s' option set to sqlite3's ':memory:' value shouldn't interfere with transaction support detection." % option
# Transaction support should be properly initialised for the 'other' DB
self.assertIsNotNone(other.features.supports_transactions, msg)
# And all the DBs should report that they support transactions
self.assertTrue(connections_support_transactions(), msg)
finally:
db.connections = old_db_connections