test_debug_sql.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import unittest
  2. from io import StringIO
  3. from django.db import connection
  4. from django.test import TestCase
  5. from django.test.runner import DiscoverRunner
  6. from .models import Person
  7. @unittest.skipUnless(connection.vendor == 'sqlite', 'Only run on sqlite so we can check output SQL.')
  8. class TestDebugSQL(unittest.TestCase):
  9. class PassingTest(TestCase):
  10. def runTest(self):
  11. Person.objects.filter(first_name='pass').count()
  12. class FailingTest(TestCase):
  13. def runTest(self):
  14. Person.objects.filter(first_name='fail').count()
  15. self.fail()
  16. class ErrorTest(TestCase):
  17. def runTest(self):
  18. Person.objects.filter(first_name='error').count()
  19. raise Exception
  20. class PassingSubTest(TestCase):
  21. def runTest(self):
  22. with self.subTest():
  23. Person.objects.filter(first_name='subtest-pass').count()
  24. class FailingSubTest(TestCase):
  25. def runTest(self):
  26. with self.subTest():
  27. Person.objects.filter(first_name='subtest-fail').count()
  28. self.fail()
  29. class ErrorSubTest(TestCase):
  30. def runTest(self):
  31. with self.subTest():
  32. Person.objects.filter(first_name='subtest-error').count()
  33. raise Exception
  34. def _test_output(self, verbosity):
  35. runner = DiscoverRunner(debug_sql=True, verbosity=0)
  36. suite = runner.test_suite()
  37. suite.addTest(self.FailingTest())
  38. suite.addTest(self.ErrorTest())
  39. suite.addTest(self.PassingTest())
  40. suite.addTest(self.PassingSubTest())
  41. suite.addTest(self.FailingSubTest())
  42. suite.addTest(self.ErrorSubTest())
  43. old_config = runner.setup_databases()
  44. stream = StringIO()
  45. resultclass = runner.get_resultclass()
  46. runner.test_runner(
  47. verbosity=verbosity,
  48. stream=stream,
  49. resultclass=resultclass,
  50. ).run(suite)
  51. runner.teardown_databases(old_config)
  52. return stream.getvalue()
  53. def test_output_normal(self):
  54. full_output = self._test_output(1)
  55. for output in self.expected_outputs:
  56. self.assertIn(output, full_output)
  57. for output in self.verbose_expected_outputs:
  58. self.assertNotIn(output, full_output)
  59. def test_output_verbose(self):
  60. full_output = self._test_output(2)
  61. for output in self.expected_outputs:
  62. self.assertIn(output, full_output)
  63. for output in self.verbose_expected_outputs:
  64. self.assertIn(output, full_output)
  65. expected_outputs = [
  66. ('''SELECT COUNT(*) AS "__count" '''
  67. '''FROM "test_runner_person" WHERE '''
  68. '''"test_runner_person"."first_name" = 'error';'''),
  69. ('''SELECT COUNT(*) AS "__count" '''
  70. '''FROM "test_runner_person" WHERE '''
  71. '''"test_runner_person"."first_name" = 'fail';'''),
  72. ('''SELECT COUNT(*) AS "__count" '''
  73. '''FROM "test_runner_person" WHERE '''
  74. '''"test_runner_person"."first_name" = 'subtest-error';'''),
  75. ('''SELECT COUNT(*) AS "__count" '''
  76. '''FROM "test_runner_person" WHERE '''
  77. '''"test_runner_person"."first_name" = 'subtest-fail';'''),
  78. ]
  79. verbose_expected_outputs = [
  80. 'runTest (test_runner.test_debug_sql.TestDebugSQL.FailingTest) ... FAIL',
  81. 'runTest (test_runner.test_debug_sql.TestDebugSQL.ErrorTest) ... ERROR',
  82. 'runTest (test_runner.test_debug_sql.TestDebugSQL.PassingTest) ... ok',
  83. # If there are errors/failures in subtests but not in test itself,
  84. # the status is not written. That behavior comes from Python.
  85. 'runTest (test_runner.test_debug_sql.TestDebugSQL.FailingSubTest) ...',
  86. 'runTest (test_runner.test_debug_sql.TestDebugSQL.ErrorSubTest) ...',
  87. ('''SELECT COUNT(*) AS "__count" '''
  88. '''FROM "test_runner_person" WHERE '''
  89. '''"test_runner_person"."first_name" = 'pass';'''),
  90. ('''SELECT COUNT(*) AS "__count" '''
  91. '''FROM "test_runner_person" WHERE '''
  92. '''"test_runner_person"."first_name" = 'subtest-pass';'''),
  93. ]