import sys import unittest from django.db import connection from django.test import TestCase from django.test.runner import DiscoverRunner from django.utils import six from django.utils.encoding import force_text 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 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()) old_config = runner.setup_databases() stream = six.StringIO() resultclass = runner.get_resultclass() runner.test_runner( verbosity=verbosity, stream=stream, resultclass=resultclass, ).run(suite) runner.teardown_databases(old_config) if six.PY2: stream.buflist = [force_text(x) for x in stream.buflist] 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';'''), ] verbose_expected_outputs = [ # Output format changed in Python 3.5+ x.format('' if sys.version_info < (3, 5) else 'TestDebugSQL.') for x in [ 'runTest (test_runner.test_debug_sql.{}FailingTest) ... FAIL', 'runTest (test_runner.test_debug_sql.{}ErrorTest) ... ERROR', 'runTest (test_runner.test_debug_sql.{}PassingTest) ... ok', ] ] + [ ('''SELECT COUNT(*) AS "__count" ''' '''FROM "test_runner_person" WHERE ''' '''"test_runner_person"."first_name" = 'pass';'''), ]