From 6143f180bfadd75f1a1d2698bd36ca8ebfdf8baf Mon Sep 17 00:00:00 2001 From: Nik Date: Fri, 5 May 2017 20:50:00 +0300 Subject: [PATCH 1/3] Test to illustrate poor `xmlrunner.extra.djangotestrunner.XMLTestRunner` extensibility --- tests/django_test.py | 18 ++++++++++++++++++ tox.ini | 1 + 2 files changed, 19 insertions(+) diff --git a/tests/django_test.py b/tests/django_test.py index d7ee698..b924c0d 100644 --- a/tests/django_test.py +++ b/tests/django_test.py @@ -4,6 +4,7 @@ import os from os import path import glob +import mock import tempfile import shutil @@ -129,3 +130,20 @@ def test_django_multiple_reports(self): self.assertTrue(test_files, 'did not generate xml reports where expected.') self.assertEqual(2, len(test_files)) + + def test_django_runner_extension(self): + from xmlrunner.extra.djangotestrunner import XMLTestRunner + + class MyDjangoRunner(XMLTestRunner): + test_runner = mock.Mock() + + self._override_settings( + TEST_OUTPUT_DIR=self.tmpdir, + TEST_OUTPUT_VERBOSE=0) + apps.populate(settings.INSTALLED_APPS) + + runner = MyDjangoRunner() + suite = runner.build_suite(test_labels=None) + runner.run_suite(suite) + + self.assertTrue(MyDjangoRunner.test_runner.called) diff --git a/tox.ini b/tox.ini index dc6c83d..1450b84 100644 --- a/tox.ini +++ b/tox.ini @@ -14,6 +14,7 @@ deps = djangolts: django>=1.8.8,<1.9.0 djangocurr: django>=1.9.1 lxml>=3.6.0 + mock commands = coverage run --append setup.py test coverage report --omit='.tox/*' From 0f0fb3efe811188499a288b60cc867688880581a Mon Sep 17 00:00:00 2001 From: Nik Date: Fri, 5 May 2017 21:38:23 +0300 Subject: [PATCH 2/3] Ability to define custom test_runner for django test runner class Move test_runner kwargs generation into separate method, like in django 1.11+ (still working in prior versions) Use `test_runner` attribute instead of hardcoded `xmlrunner.XMLTestRunner` --- xmlrunner/extra/djangotestrunner.py | 46 +++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/xmlrunner/extra/djangotestrunner.py b/xmlrunner/extra/djangotestrunner.py index ee07f63..d49bf71 100644 --- a/xmlrunner/extra/djangotestrunner.py +++ b/xmlrunner/extra/djangotestrunner.py @@ -17,27 +17,47 @@ class XMLTestRunner(DiscoverRunner): + test_runner = xmlrunner.XMLTestRunner - def run_suite(self, suite, **kwargs): - dummy = kwargs # unused + def get_resultclass(self): + # Django provides `DebugSQLTextTestResult` if `debug_sql` argument is True + # To use `xmlrunner.result._XMLTestResult` we supress default behavior + return None + + def get_test_runner_kwargs(self): + # We use separate verbosity setting for our runner verbosity = getattr(settings, 'TEST_OUTPUT_VERBOSE', 1) - # XXX: verbosity = self.verbosity if isinstance(verbosity, bool): verbosity = (1, 2)[verbosity] - descriptions = getattr(settings, 'TEST_OUTPUT_DESCRIPTIONS', False) + verbosity = verbosity # not self.verbosity + output_dir = getattr(settings, 'TEST_OUTPUT_DIR', '.') single_file = getattr(settings, 'TEST_OUTPUT_FILE_NAME', None) - kwargs = dict( - verbosity=verbosity, descriptions=descriptions, - failfast=self.failfast) + # For single file case we are able to create file here + # But for multiple files case files will be created inside runner/results if single_file is not None: if not os.path.exists(output_dir): os.makedirs(output_dir) + + if single_file is None: # output is a stream + output = output_dir + else: # output is a folder file_path = os.path.join(output_dir, single_file) - with open(file_path, 'wb') as xml: - return xmlrunner.XMLTestRunner( - output=xml, **kwargs).run(suite) - else: - return xmlrunner.XMLTestRunner( - output=output_dir, **kwargs).run(suite) + output = open(file_path, 'wb') + + return dict( + verbosity=verbosity, + descriptions=getattr(settings, 'TEST_OUTPUT_DESCRIPTIONS', False), + failfast=self.failfast, + resultclass=self.get_resultclass(), + output=output, + ) + + def run_suite(self, suite, **kwargs): + kwargs = self.get_test_runner_kwargs() + runner = self.test_runner(**kwargs) + results = runner.run(suite) + if hasattr(kwargs['output'], 'close'): + kwargs['output'].close() + return results From 2877243e52a53c66bb97ebca6571d24012a3cd84 Mon Sep 17 00:00:00 2001 From: Nik Date: Wed, 17 May 2017 21:14:28 +0300 Subject: [PATCH 3/3] Fix local var reuse, fix misleading comments, fix redundant if --- xmlrunner/extra/djangotestrunner.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/xmlrunner/extra/djangotestrunner.py b/xmlrunner/extra/djangotestrunner.py index d49bf71..29b4e39 100644 --- a/xmlrunner/extra/djangotestrunner.py +++ b/xmlrunner/extra/djangotestrunner.py @@ -36,13 +36,11 @@ def get_test_runner_kwargs(self): # For single file case we are able to create file here # But for multiple files case files will be created inside runner/results - if single_file is not None: + if single_file is None: # output will be a path (folder) + output = output_dir + else: # output will be a stream if not os.path.exists(output_dir): os.makedirs(output_dir) - - if single_file is None: # output is a stream - output = output_dir - else: # output is a folder file_path = os.path.join(output_dir, single_file) output = open(file_path, 'wb') @@ -55,9 +53,9 @@ def get_test_runner_kwargs(self): ) def run_suite(self, suite, **kwargs): - kwargs = self.get_test_runner_kwargs() - runner = self.test_runner(**kwargs) + runner_kwargs = self.get_test_runner_kwargs() + runner = self.test_runner(**runner_kwargs) results = runner.run(suite) - if hasattr(kwargs['output'], 'close'): - kwargs['output'].close() + if hasattr(runner_kwargs['output'], 'close'): + runner_kwargs['output'].close() return results