tests.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. """
  2. Tests for django test runner
  3. """
  4. import unittest
  5. from unittest import mock
  6. from admin_scripts.tests import AdminScriptTestCase
  7. from django import db
  8. from django.conf import settings
  9. from django.core.exceptions import ImproperlyConfigured
  10. from django.core.management import call_command
  11. from django.core.management.base import SystemCheckError
  12. from django.test import (
  13. SimpleTestCase, TransactionTestCase, skipUnlessDBFeature,
  14. )
  15. from django.test.runner import DiscoverRunner
  16. from django.test.testcases import connections_support_transactions
  17. from django.test.utils import (
  18. captured_stderr, dependency_ordered, get_unique_databases_and_mirrors,
  19. iter_test_cases,
  20. )
  21. from django.utils.deprecation import RemovedInDjango50Warning
  22. from .models import B, Person, Through
  23. class MySuite:
  24. def __init__(self):
  25. self.tests = []
  26. def addTest(self, test):
  27. self.tests.append(test)
  28. def __iter__(self):
  29. yield from self.tests
  30. class IterTestCasesTests(unittest.TestCase):
  31. def make_test_suite(self, suite=None, suite_class=None):
  32. if suite_class is None:
  33. suite_class = unittest.TestSuite
  34. if suite is None:
  35. suite = suite_class()
  36. class Tests1(unittest.TestCase):
  37. def test1(self):
  38. pass
  39. def test2(self):
  40. pass
  41. class Tests2(unittest.TestCase):
  42. def test1(self):
  43. pass
  44. def test2(self):
  45. pass
  46. loader = unittest.defaultTestLoader
  47. for test_cls in (Tests1, Tests2):
  48. tests = loader.loadTestsFromTestCase(test_cls)
  49. subsuite = suite_class()
  50. # Only use addTest() to simplify testing a custom TestSuite.
  51. for test in tests:
  52. subsuite.addTest(test)
  53. suite.addTest(subsuite)
  54. return suite
  55. def assertTestNames(self, tests, expected):
  56. # Each test.id() has a form like the following:
  57. # "test_runner.tests.IterTestCasesTests.test_iter_test_cases.<locals>.Tests1.test1".
  58. # It suffices to check only the last two parts.
  59. names = ['.'.join(test.id().split('.')[-2:]) for test in tests]
  60. self.assertEqual(names, expected)
  61. def test_basic(self):
  62. suite = self.make_test_suite()
  63. tests = iter_test_cases(suite)
  64. self.assertTestNames(tests, expected=[
  65. 'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2',
  66. ])
  67. def test_reverse(self):
  68. suite = self.make_test_suite()
  69. tests = iter_test_cases(suite, reverse=True)
  70. self.assertTestNames(tests, expected=[
  71. 'Tests2.test2', 'Tests2.test1', 'Tests1.test2', 'Tests1.test1',
  72. ])
  73. def test_custom_test_suite_class(self):
  74. suite = self.make_test_suite(suite_class=MySuite)
  75. tests = iter_test_cases(suite)
  76. self.assertTestNames(tests, expected=[
  77. 'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2',
  78. ])
  79. def test_mixed_test_suite_classes(self):
  80. suite = self.make_test_suite(suite=MySuite())
  81. child_suite = list(suite)[0]
  82. self.assertNotIsInstance(child_suite, MySuite)
  83. tests = list(iter_test_cases(suite))
  84. self.assertEqual(len(tests), 4)
  85. self.assertNotIsInstance(tests[0], unittest.TestSuite)
  86. class DependencyOrderingTests(unittest.TestCase):
  87. def test_simple_dependencies(self):
  88. raw = [
  89. ('s1', ('s1_db', ['alpha'])),
  90. ('s2', ('s2_db', ['bravo'])),
  91. ('s3', ('s3_db', ['charlie'])),
  92. ]
  93. dependencies = {
  94. 'alpha': ['charlie'],
  95. 'bravo': ['charlie'],
  96. }
  97. ordered = dependency_ordered(raw, dependencies=dependencies)
  98. ordered_sigs = [sig for sig, value in ordered]
  99. self.assertIn('s1', ordered_sigs)
  100. self.assertIn('s2', ordered_sigs)
  101. self.assertIn('s3', ordered_sigs)
  102. self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1'))
  103. self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2'))
  104. def test_chained_dependencies(self):
  105. raw = [
  106. ('s1', ('s1_db', ['alpha'])),
  107. ('s2', ('s2_db', ['bravo'])),
  108. ('s3', ('s3_db', ['charlie'])),
  109. ]
  110. dependencies = {
  111. 'alpha': ['bravo'],
  112. 'bravo': ['charlie'],
  113. }
  114. ordered = dependency_ordered(raw, dependencies=dependencies)
  115. ordered_sigs = [sig for sig, value in ordered]
  116. self.assertIn('s1', ordered_sigs)
  117. self.assertIn('s2', ordered_sigs)
  118. self.assertIn('s3', ordered_sigs)
  119. # Explicit dependencies
  120. self.assertLess(ordered_sigs.index('s2'), ordered_sigs.index('s1'))
  121. self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2'))
  122. # Implied dependencies
  123. self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1'))
  124. def test_multiple_dependencies(self):
  125. raw = [
  126. ('s1', ('s1_db', ['alpha'])),
  127. ('s2', ('s2_db', ['bravo'])),
  128. ('s3', ('s3_db', ['charlie'])),
  129. ('s4', ('s4_db', ['delta'])),
  130. ]
  131. dependencies = {
  132. 'alpha': ['bravo', 'delta'],
  133. 'bravo': ['charlie'],
  134. 'delta': ['charlie'],
  135. }
  136. ordered = dependency_ordered(raw, dependencies=dependencies)
  137. ordered_sigs = [sig for sig, aliases in ordered]
  138. self.assertIn('s1', ordered_sigs)
  139. self.assertIn('s2', ordered_sigs)
  140. self.assertIn('s3', ordered_sigs)
  141. self.assertIn('s4', ordered_sigs)
  142. # Explicit dependencies
  143. self.assertLess(ordered_sigs.index('s2'), ordered_sigs.index('s1'))
  144. self.assertLess(ordered_sigs.index('s4'), ordered_sigs.index('s1'))
  145. self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s2'))
  146. self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s4'))
  147. # Implicit dependencies
  148. self.assertLess(ordered_sigs.index('s3'), ordered_sigs.index('s1'))
  149. def test_circular_dependencies(self):
  150. raw = [
  151. ('s1', ('s1_db', ['alpha'])),
  152. ('s2', ('s2_db', ['bravo'])),
  153. ]
  154. dependencies = {
  155. 'bravo': ['alpha'],
  156. 'alpha': ['bravo'],
  157. }
  158. with self.assertRaises(ImproperlyConfigured):
  159. dependency_ordered(raw, dependencies=dependencies)
  160. def test_own_alias_dependency(self):
  161. raw = [
  162. ('s1', ('s1_db', ['alpha', 'bravo']))
  163. ]
  164. dependencies = {
  165. 'alpha': ['bravo']
  166. }
  167. with self.assertRaises(ImproperlyConfigured):
  168. dependency_ordered(raw, dependencies=dependencies)
  169. # reordering aliases shouldn't matter
  170. raw = [
  171. ('s1', ('s1_db', ['bravo', 'alpha']))
  172. ]
  173. with self.assertRaises(ImproperlyConfigured):
  174. dependency_ordered(raw, dependencies=dependencies)
  175. class MockTestRunner:
  176. def __init__(self, *args, **kwargs):
  177. pass
  178. MockTestRunner.run_tests = mock.Mock(return_value=[])
  179. class ManageCommandTests(unittest.TestCase):
  180. def test_custom_test_runner(self):
  181. call_command('test', 'sites',
  182. testrunner='test_runner.tests.MockTestRunner')
  183. MockTestRunner.run_tests.assert_called_with(('sites',))
  184. def test_bad_test_runner(self):
  185. with self.assertRaises(AttributeError):
  186. call_command('test', 'sites', testrunner='test_runner.NonexistentRunner')
  187. def test_time_recorded(self):
  188. with captured_stderr() as stderr:
  189. call_command('test', '--timing', 'sites', testrunner='test_runner.tests.MockTestRunner')
  190. self.assertIn('Total run took', stderr.getvalue())
  191. class CustomTestRunnerOptionsSettingsTests(AdminScriptTestCase):
  192. """
  193. Custom runners can add command line arguments. The runner is specified
  194. through a settings file.
  195. """
  196. def setUp(self):
  197. super().setUp()
  198. settings = {
  199. 'TEST_RUNNER': '\'test_runner.runner.CustomOptionsTestRunner\'',
  200. }
  201. self.write_settings('settings.py', sdict=settings)
  202. def test_default_options(self):
  203. args = ['test', '--settings=test_project.settings']
  204. out, err = self.run_django_admin(args)
  205. self.assertNoOutput(err)
  206. self.assertOutput(out, '1:2:3')
  207. def test_default_and_given_options(self):
  208. args = ['test', '--settings=test_project.settings', '--option_b=foo']
  209. out, err = self.run_django_admin(args)
  210. self.assertNoOutput(err)
  211. self.assertOutput(out, '1:foo:3')
  212. def test_option_name_and_value_separated(self):
  213. args = ['test', '--settings=test_project.settings', '--option_b', 'foo']
  214. out, err = self.run_django_admin(args)
  215. self.assertNoOutput(err)
  216. self.assertOutput(out, '1:foo:3')
  217. def test_all_options_given(self):
  218. args = ['test', '--settings=test_project.settings', '--option_a=bar',
  219. '--option_b=foo', '--option_c=31337']
  220. out, err = self.run_django_admin(args)
  221. self.assertNoOutput(err)
  222. self.assertOutput(out, 'bar:foo:31337')
  223. class CustomTestRunnerOptionsCmdlineTests(AdminScriptTestCase):
  224. """
  225. Custom runners can add command line arguments when the runner is specified
  226. using --testrunner.
  227. """
  228. def setUp(self):
  229. super().setUp()
  230. self.write_settings('settings.py')
  231. def test_testrunner_option(self):
  232. args = [
  233. 'test', '--testrunner', 'test_runner.runner.CustomOptionsTestRunner',
  234. '--option_a=bar', '--option_b=foo', '--option_c=31337'
  235. ]
  236. out, err = self.run_django_admin(args, 'test_project.settings')
  237. self.assertNoOutput(err)
  238. self.assertOutput(out, 'bar:foo:31337')
  239. def test_testrunner_equals(self):
  240. args = [
  241. 'test', '--testrunner=test_runner.runner.CustomOptionsTestRunner',
  242. '--option_a=bar', '--option_b=foo', '--option_c=31337'
  243. ]
  244. out, err = self.run_django_admin(args, 'test_project.settings')
  245. self.assertNoOutput(err)
  246. self.assertOutput(out, 'bar:foo:31337')
  247. def test_no_testrunner(self):
  248. args = ['test', '--testrunner']
  249. out, err = self.run_django_admin(args, 'test_project.settings')
  250. self.assertIn('usage', err)
  251. self.assertNotIn('Traceback', err)
  252. self.assertNoOutput(out)
  253. class Ticket17477RegressionTests(AdminScriptTestCase):
  254. def setUp(self):
  255. super().setUp()
  256. self.write_settings('settings.py')
  257. def test_ticket_17477(self):
  258. """'manage.py help test' works after r16352."""
  259. args = ['help', 'test']
  260. out, err = self.run_manage(args)
  261. self.assertNoOutput(err)
  262. class SQLiteInMemoryTestDbs(TransactionTestCase):
  263. available_apps = ['test_runner']
  264. databases = {'default', 'other'}
  265. @unittest.skipUnless(all(db.connections[conn].vendor == 'sqlite' for conn in db.connections),
  266. "This is an sqlite-specific issue")
  267. def test_transaction_support(self):
  268. # Assert connections mocking is appropriately applied by preventing
  269. # any attempts at calling create_test_db on the global connection
  270. # objects.
  271. for connection in db.connections.all():
  272. create_test_db = mock.patch.object(
  273. connection.creation,
  274. 'create_test_db',
  275. side_effect=AssertionError("Global connection object shouldn't be manipulated.")
  276. )
  277. create_test_db.start()
  278. self.addCleanup(create_test_db.stop)
  279. for option_key, option_value in (
  280. ('NAME', ':memory:'), ('TEST', {'NAME': ':memory:'})):
  281. tested_connections = db.ConnectionHandler({
  282. 'default': {
  283. 'ENGINE': 'django.db.backends.sqlite3',
  284. option_key: option_value,
  285. },
  286. 'other': {
  287. 'ENGINE': 'django.db.backends.sqlite3',
  288. option_key: option_value,
  289. },
  290. })
  291. with mock.patch('django.test.utils.connections', new=tested_connections):
  292. other = tested_connections['other']
  293. DiscoverRunner(verbosity=0).setup_databases()
  294. msg = (
  295. "DATABASES setting '%s' option set to sqlite3's ':memory:' value "
  296. "shouldn't interfere with transaction support detection." % option_key
  297. )
  298. # Transaction support is properly initialized for the 'other' DB.
  299. self.assertTrue(other.features.supports_transactions, msg)
  300. # And all the DBs report that they support transactions.
  301. self.assertTrue(connections_support_transactions(), msg)
  302. class DummyBackendTest(unittest.TestCase):
  303. def test_setup_databases(self):
  304. """
  305. setup_databases() doesn't fail with dummy database backend.
  306. """
  307. tested_connections = db.ConnectionHandler({})
  308. with mock.patch('django.test.utils.connections', new=tested_connections):
  309. runner_instance = DiscoverRunner(verbosity=0)
  310. old_config = runner_instance.setup_databases()
  311. runner_instance.teardown_databases(old_config)
  312. class AliasedDefaultTestSetupTest(unittest.TestCase):
  313. def test_setup_aliased_default_database(self):
  314. """
  315. setup_databases() doesn't fail when 'default' is aliased
  316. """
  317. tested_connections = db.ConnectionHandler({
  318. 'default': {
  319. 'NAME': 'dummy'
  320. },
  321. 'aliased': {
  322. 'NAME': 'dummy'
  323. }
  324. })
  325. with mock.patch('django.test.utils.connections', new=tested_connections):
  326. runner_instance = DiscoverRunner(verbosity=0)
  327. old_config = runner_instance.setup_databases()
  328. runner_instance.teardown_databases(old_config)
  329. class SetupDatabasesTests(SimpleTestCase):
  330. def setUp(self):
  331. self.runner_instance = DiscoverRunner(verbosity=0)
  332. def test_setup_aliased_databases(self):
  333. tested_connections = db.ConnectionHandler({
  334. 'default': {
  335. 'ENGINE': 'django.db.backends.dummy',
  336. 'NAME': 'dbname',
  337. },
  338. 'other': {
  339. 'ENGINE': 'django.db.backends.dummy',
  340. 'NAME': 'dbname',
  341. }
  342. })
  343. with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation:
  344. with mock.patch('django.test.utils.connections', new=tested_connections):
  345. old_config = self.runner_instance.setup_databases()
  346. self.runner_instance.teardown_databases(old_config)
  347. mocked_db_creation.return_value.destroy_test_db.assert_called_once_with('dbname', 0, False)
  348. def test_setup_test_database_aliases(self):
  349. """
  350. The default database must be the first because data migrations
  351. use the default alias by default.
  352. """
  353. tested_connections = db.ConnectionHandler({
  354. 'other': {
  355. 'ENGINE': 'django.db.backends.dummy',
  356. 'NAME': 'dbname',
  357. },
  358. 'default': {
  359. 'ENGINE': 'django.db.backends.dummy',
  360. 'NAME': 'dbname',
  361. }
  362. })
  363. with mock.patch('django.test.utils.connections', new=tested_connections):
  364. test_databases, _ = get_unique_databases_and_mirrors()
  365. self.assertEqual(
  366. test_databases,
  367. {
  368. ('', '', 'django.db.backends.dummy', 'test_dbname'): (
  369. 'dbname',
  370. ['default', 'other'],
  371. ),
  372. },
  373. )
  374. def test_destroy_test_db_restores_db_name(self):
  375. tested_connections = db.ConnectionHandler({
  376. 'default': {
  377. 'ENGINE': settings.DATABASES[db.DEFAULT_DB_ALIAS]["ENGINE"],
  378. 'NAME': 'xxx_test_database',
  379. },
  380. })
  381. # Using the real current name as old_name to not mess with the test suite.
  382. old_name = settings.DATABASES[db.DEFAULT_DB_ALIAS]["NAME"]
  383. with mock.patch('django.db.connections', new=tested_connections):
  384. tested_connections['default'].creation.destroy_test_db(old_name, verbosity=0, keepdb=True)
  385. self.assertEqual(tested_connections['default'].settings_dict["NAME"], old_name)
  386. def test_serialization(self):
  387. tested_connections = db.ConnectionHandler({
  388. 'default': {
  389. 'ENGINE': 'django.db.backends.dummy',
  390. },
  391. })
  392. with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation:
  393. with mock.patch('django.test.utils.connections', new=tested_connections):
  394. self.runner_instance.setup_databases()
  395. mocked_db_creation.return_value.create_test_db.assert_called_once_with(
  396. verbosity=0, autoclobber=False, serialize=True, keepdb=False
  397. )
  398. def test_serialized_off(self):
  399. tested_connections = db.ConnectionHandler({
  400. 'default': {
  401. 'ENGINE': 'django.db.backends.dummy',
  402. 'TEST': {'SERIALIZE': False},
  403. },
  404. })
  405. msg = (
  406. 'The SERIALIZE test database setting is deprecated as it can be '
  407. 'inferred from the TestCase/TransactionTestCase.databases that '
  408. 'enable the serialized_rollback feature.'
  409. )
  410. with mock.patch('django.db.backends.dummy.base.DatabaseWrapper.creation_class') as mocked_db_creation:
  411. with mock.patch('django.test.utils.connections', new=tested_connections):
  412. with self.assertWarnsMessage(RemovedInDjango50Warning, msg):
  413. self.runner_instance.setup_databases()
  414. mocked_db_creation.return_value.create_test_db.assert_called_once_with(
  415. verbosity=0, autoclobber=False, serialize=False, keepdb=False
  416. )
  417. @skipUnlessDBFeature('supports_sequence_reset')
  418. class AutoIncrementResetTest(TransactionTestCase):
  419. """
  420. Creating the same models in different test methods receive the same PK
  421. values since the sequences are reset before each test method.
  422. """
  423. available_apps = ['test_runner']
  424. reset_sequences = True
  425. def _test(self):
  426. # Regular model
  427. p = Person.objects.create(first_name='Jack', last_name='Smith')
  428. self.assertEqual(p.pk, 1)
  429. # Auto-created many-to-many through model
  430. p.friends.add(Person.objects.create(first_name='Jacky', last_name='Smith'))
  431. self.assertEqual(p.friends.through.objects.first().pk, 1)
  432. # Many-to-many through model
  433. b = B.objects.create()
  434. t = Through.objects.create(person=p, b=b)
  435. self.assertEqual(t.pk, 1)
  436. def test_autoincrement_reset1(self):
  437. self._test()
  438. def test_autoincrement_reset2(self):
  439. self._test()
  440. class EmptyDefaultDatabaseTest(unittest.TestCase):
  441. def test_empty_default_database(self):
  442. """
  443. An empty default database in settings does not raise an ImproperlyConfigured
  444. error when running a unit test that does not use a database.
  445. """
  446. tested_connections = db.ConnectionHandler({'default': {}})
  447. with mock.patch('django.db.connections', new=tested_connections):
  448. connection = tested_connections[db.utils.DEFAULT_DB_ALIAS]
  449. self.assertEqual(connection.settings_dict['ENGINE'], 'django.db.backends.dummy')
  450. connections_support_transactions()
  451. class RunTestsExceptionHandlingTests(unittest.TestCase):
  452. def test_run_checks_raises(self):
  453. """
  454. Teardown functions are run when run_checks() raises SystemCheckError.
  455. """
  456. with mock.patch('django.test.runner.DiscoverRunner.setup_test_environment'), \
  457. mock.patch('django.test.runner.DiscoverRunner.setup_databases'), \
  458. mock.patch('django.test.runner.DiscoverRunner.build_suite'), \
  459. mock.patch('django.test.runner.DiscoverRunner.run_checks', side_effect=SystemCheckError), \
  460. mock.patch('django.test.runner.DiscoverRunner.teardown_databases') as teardown_databases, \
  461. mock.patch('django.test.runner.DiscoverRunner.teardown_test_environment') as teardown_test_environment:
  462. runner = DiscoverRunner(verbosity=0, interactive=False)
  463. with self.assertRaises(SystemCheckError):
  464. runner.run_tests(['test_runner_apps.sample.tests_sample.TestDjangoTestCase'])
  465. self.assertTrue(teardown_databases.called)
  466. self.assertTrue(teardown_test_environment.called)
  467. def test_run_checks_raises_and_teardown_raises(self):
  468. """
  469. SystemCheckError is surfaced when run_checks() raises SystemCheckError
  470. and teardown databases() raises ValueError.
  471. """
  472. with mock.patch('django.test.runner.DiscoverRunner.setup_test_environment'), \
  473. mock.patch('django.test.runner.DiscoverRunner.setup_databases'), \
  474. mock.patch('django.test.runner.DiscoverRunner.build_suite'), \
  475. mock.patch('django.test.runner.DiscoverRunner.run_checks', side_effect=SystemCheckError), \
  476. mock.patch('django.test.runner.DiscoverRunner.teardown_databases', side_effect=ValueError) \
  477. as teardown_databases, \
  478. mock.patch('django.test.runner.DiscoverRunner.teardown_test_environment') as teardown_test_environment:
  479. runner = DiscoverRunner(verbosity=0, interactive=False)
  480. with self.assertRaises(SystemCheckError):
  481. runner.run_tests(['test_runner_apps.sample.tests_sample.TestDjangoTestCase'])
  482. self.assertTrue(teardown_databases.called)
  483. self.assertFalse(teardown_test_environment.called)
  484. def test_run_checks_passes_and_teardown_raises(self):
  485. """
  486. Exceptions on teardown are surfaced if no exceptions happen during
  487. run_checks().
  488. """
  489. with mock.patch('django.test.runner.DiscoverRunner.setup_test_environment'), \
  490. mock.patch('django.test.runner.DiscoverRunner.setup_databases'), \
  491. mock.patch('django.test.runner.DiscoverRunner.build_suite'), \
  492. mock.patch('django.test.runner.DiscoverRunner.run_checks'), \
  493. mock.patch('django.test.runner.DiscoverRunner.teardown_databases', side_effect=ValueError) \
  494. as teardown_databases, \
  495. mock.patch('django.test.runner.DiscoverRunner.teardown_test_environment') as teardown_test_environment:
  496. runner = DiscoverRunner(verbosity=0, interactive=False)
  497. with self.assertRaises(ValueError):
  498. # Suppress the output when running TestDjangoTestCase.
  499. with mock.patch('sys.stderr'):
  500. runner.run_tests(['test_runner_apps.sample.tests_sample.TestDjangoTestCase'])
  501. self.assertTrue(teardown_databases.called)
  502. self.assertFalse(teardown_test_environment.called)