Skip to content

Commit 8e53812

Browse files
authored
Merge pull request #148 from Nnonexistent/django_extensibility
Ability to define custom test_runner for Django test runner
2 parents 14fa2ff + 2877243 commit 8e53812

File tree

3 files changed

+51
-14
lines changed

3 files changed

+51
-14
lines changed

tests/django_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
from os import path
66
import glob
7+
import mock
78
import tempfile
89
import shutil
910

@@ -129,3 +130,20 @@ def test_django_multiple_reports(self):
129130
self.assertTrue(test_files,
130131
'did not generate xml reports where expected.')
131132
self.assertEqual(2, len(test_files))
133+
134+
def test_django_runner_extension(self):
135+
from xmlrunner.extra.djangotestrunner import XMLTestRunner
136+
137+
class MyDjangoRunner(XMLTestRunner):
138+
test_runner = mock.Mock()
139+
140+
self._override_settings(
141+
TEST_OUTPUT_DIR=self.tmpdir,
142+
TEST_OUTPUT_VERBOSE=0)
143+
apps.populate(settings.INSTALLED_APPS)
144+
145+
runner = MyDjangoRunner()
146+
suite = runner.build_suite(test_labels=None)
147+
runner.run_suite(suite)
148+
149+
self.assertTrue(MyDjangoRunner.test_runner.called)

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ deps =
1414
djangolts: django>=1.8.8,<1.9.0
1515
djangocurr: django>=1.9.1
1616
lxml>=3.6.0
17+
mock
1718
commands =
1819
coverage run --append setup.py test
1920
coverage report --omit='.tox/*'

xmlrunner/extra/djangotestrunner.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,45 @@
1717

1818

1919
class XMLTestRunner(DiscoverRunner):
20+
test_runner = xmlrunner.XMLTestRunner
2021

21-
def run_suite(self, suite, **kwargs):
22-
dummy = kwargs # unused
22+
def get_resultclass(self):
23+
# Django provides `DebugSQLTextTestResult` if `debug_sql` argument is True
24+
# To use `xmlrunner.result._XMLTestResult` we supress default behavior
25+
return None
26+
27+
def get_test_runner_kwargs(self):
28+
# We use separate verbosity setting for our runner
2329
verbosity = getattr(settings, 'TEST_OUTPUT_VERBOSE', 1)
24-
# XXX: verbosity = self.verbosity
2530
if isinstance(verbosity, bool):
2631
verbosity = (1, 2)[verbosity]
27-
descriptions = getattr(settings, 'TEST_OUTPUT_DESCRIPTIONS', False)
32+
verbosity = verbosity # not self.verbosity
33+
2834
output_dir = getattr(settings, 'TEST_OUTPUT_DIR', '.')
2935
single_file = getattr(settings, 'TEST_OUTPUT_FILE_NAME', None)
3036

31-
kwargs = dict(
32-
verbosity=verbosity, descriptions=descriptions,
33-
failfast=self.failfast)
34-
if single_file is not None:
37+
# For single file case we are able to create file here
38+
# But for multiple files case files will be created inside runner/results
39+
if single_file is None: # output will be a path (folder)
40+
output = output_dir
41+
else: # output will be a stream
3542
if not os.path.exists(output_dir):
3643
os.makedirs(output_dir)
3744
file_path = os.path.join(output_dir, single_file)
38-
with open(file_path, 'wb') as xml:
39-
return xmlrunner.XMLTestRunner(
40-
output=xml, **kwargs).run(suite)
41-
else:
42-
return xmlrunner.XMLTestRunner(
43-
output=output_dir, **kwargs).run(suite)
45+
output = open(file_path, 'wb')
46+
47+
return dict(
48+
verbosity=verbosity,
49+
descriptions=getattr(settings, 'TEST_OUTPUT_DESCRIPTIONS', False),
50+
failfast=self.failfast,
51+
resultclass=self.get_resultclass(),
52+
output=output,
53+
)
54+
55+
def run_suite(self, suite, **kwargs):
56+
runner_kwargs = self.get_test_runner_kwargs()
57+
runner = self.test_runner(**runner_kwargs)
58+
results = runner.run(suite)
59+
if hasattr(runner_kwargs['output'], 'close'):
60+
runner_kwargs['output'].close()
61+
return results

0 commit comments

Comments
 (0)