mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			154 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import unittest
 | |
| from io import StringIO
 | |
| 
 | |
| from django.db import connection
 | |
| from django.test import TestCase
 | |
| from django.test.runner import DiscoverRunner
 | |
| from django.utils.version import PY311
 | |
| 
 | |
| from .models import Person
 | |
| 
 | |
| 
 | |
| @unittest.skipUnless(
 | |
|     connection.vendor == "sqlite", "Only run on sqlite so we can check output SQL."
 | |
| )
 | |
| class TestDebugSQL(unittest.TestCase):
 | |
|     class PassingTest(TestCase):
 | |
|         def runTest(self):
 | |
|             Person.objects.filter(first_name="pass").count()
 | |
| 
 | |
|     class FailingTest(TestCase):
 | |
|         def runTest(self):
 | |
|             Person.objects.filter(first_name="fail").count()
 | |
|             self.fail()
 | |
| 
 | |
|     class ErrorTest(TestCase):
 | |
|         def runTest(self):
 | |
|             Person.objects.filter(first_name="error").count()
 | |
|             raise Exception
 | |
| 
 | |
|     class ErrorSetUpTestDataTest(TestCase):
 | |
|         @classmethod
 | |
|         def setUpTestData(cls):
 | |
|             raise Exception
 | |
| 
 | |
|         def runTest(self):
 | |
|             pass
 | |
| 
 | |
|     class PassingSubTest(TestCase):
 | |
|         def runTest(self):
 | |
|             with self.subTest():
 | |
|                 Person.objects.filter(first_name="subtest-pass").count()
 | |
| 
 | |
|     class FailingSubTest(TestCase):
 | |
|         def runTest(self):
 | |
|             with self.subTest():
 | |
|                 Person.objects.filter(first_name="subtest-fail").count()
 | |
|                 self.fail()
 | |
| 
 | |
|     class ErrorSubTest(TestCase):
 | |
|         def runTest(self):
 | |
|             with self.subTest():
 | |
|                 Person.objects.filter(first_name="subtest-error").count()
 | |
|                 raise Exception
 | |
| 
 | |
|     def _test_output(self, verbosity):
 | |
|         runner = DiscoverRunner(debug_sql=True, verbosity=0)
 | |
|         suite = runner.test_suite()
 | |
|         suite.addTest(self.FailingTest())
 | |
|         suite.addTest(self.ErrorTest())
 | |
|         suite.addTest(self.PassingTest())
 | |
|         suite.addTest(self.PassingSubTest())
 | |
|         suite.addTest(self.FailingSubTest())
 | |
|         suite.addTest(self.ErrorSubTest())
 | |
|         old_config = runner.setup_databases()
 | |
|         stream = StringIO()
 | |
|         resultclass = runner.get_resultclass()
 | |
|         runner.test_runner(
 | |
|             verbosity=verbosity,
 | |
|             stream=stream,
 | |
|             resultclass=resultclass,
 | |
|         ).run(suite)
 | |
|         runner.teardown_databases(old_config)
 | |
| 
 | |
|         return stream.getvalue()
 | |
| 
 | |
|     def test_output_normal(self):
 | |
|         full_output = self._test_output(1)
 | |
|         for output in self.expected_outputs:
 | |
|             self.assertIn(output, full_output)
 | |
|         for output in self.verbose_expected_outputs:
 | |
|             self.assertNotIn(output, full_output)
 | |
| 
 | |
|     def test_output_verbose(self):
 | |
|         full_output = self._test_output(2)
 | |
|         for output in self.expected_outputs:
 | |
|             self.assertIn(output, full_output)
 | |
|         for output in self.verbose_expected_outputs:
 | |
|             self.assertIn(output, full_output)
 | |
| 
 | |
|     expected_outputs = [
 | |
|         (
 | |
|             """SELECT COUNT(*) AS "__count" """
 | |
|             """FROM "test_runner_person" WHERE """
 | |
|             """"test_runner_person"."first_name" = 'error';"""
 | |
|         ),
 | |
|         (
 | |
|             """SELECT COUNT(*) AS "__count" """
 | |
|             """FROM "test_runner_person" WHERE """
 | |
|             """"test_runner_person"."first_name" = 'fail';"""
 | |
|         ),
 | |
|         (
 | |
|             """SELECT COUNT(*) AS "__count" """
 | |
|             """FROM "test_runner_person" WHERE """
 | |
|             """"test_runner_person"."first_name" = 'subtest-error';"""
 | |
|         ),
 | |
|         (
 | |
|             """SELECT COUNT(*) AS "__count" """
 | |
|             """FROM "test_runner_person" WHERE """
 | |
|             """"test_runner_person"."first_name" = 'subtest-fail';"""
 | |
|         ),
 | |
|     ]
 | |
| 
 | |
|     # Python 3.11 uses fully qualified test name in the output.
 | |
|     method_name = ".runTest" if PY311 else ""
 | |
|     test_class_path = "test_runner.test_debug_sql.TestDebugSQL"
 | |
|     verbose_expected_outputs = [
 | |
|         f"runTest ({test_class_path}.FailingTest{method_name}) ... FAIL",
 | |
|         f"runTest ({test_class_path}.ErrorTest{method_name}) ... ERROR",
 | |
|         f"runTest ({test_class_path}.PassingTest{method_name}) ... ok",
 | |
|         # If there are errors/failures in subtests but not in test itself,
 | |
|         # the status is not written. That behavior comes from Python.
 | |
|         f"runTest ({test_class_path}.FailingSubTest{method_name}) ...",
 | |
|         f"runTest ({test_class_path}.ErrorSubTest{method_name}) ...",
 | |
|         (
 | |
|             """SELECT COUNT(*) AS "__count" """
 | |
|             """FROM "test_runner_person" WHERE """
 | |
|             """"test_runner_person"."first_name" = 'pass';"""
 | |
|         ),
 | |
|         (
 | |
|             """SELECT COUNT(*) AS "__count" """
 | |
|             """FROM "test_runner_person" WHERE """
 | |
|             """"test_runner_person"."first_name" = 'subtest-pass';"""
 | |
|         ),
 | |
|     ]
 | |
| 
 | |
|     def test_setupclass_exception(self):
 | |
|         runner = DiscoverRunner(debug_sql=True, verbosity=0)
 | |
|         suite = runner.test_suite()
 | |
|         suite.addTest(self.ErrorSetUpTestDataTest())
 | |
|         old_config = runner.setup_databases()
 | |
|         stream = StringIO()
 | |
|         runner.test_runner(
 | |
|             verbosity=0,
 | |
|             stream=stream,
 | |
|             resultclass=runner.get_resultclass(),
 | |
|         ).run(suite)
 | |
|         runner.teardown_databases(old_config)
 | |
|         output = stream.getvalue()
 | |
|         self.assertIn(
 | |
|             "ERROR: setUpClass "
 | |
|             "(test_runner.test_debug_sql.TestDebugSQL.ErrorSetUpTestDataTest)",
 | |
|             output,
 | |
|         )
 |