mbligh | 4205d89 | 2008-07-14 16:23:20 +0000 | [diff] [blame] | 1 | import common |
mbligh | e8819cd | 2008-02-15 16:48:40 +0000 | [diff] [blame] | 2 | import os, doctest, glob, sys |
showard | 2e490cc | 2008-10-08 19:15:45 +0000 | [diff] [blame] | 3 | from django.conf import settings |
showard | a5288b4 | 2009-07-28 20:06:08 +0000 | [diff] [blame] | 4 | from django.db import connection |
| 5 | import django.test.utils |
mbligh | e8819cd | 2008-02-15 16:48:40 +0000 | [diff] [blame] | 6 | |
| 7 | # doctest takes a copy+paste log of a Python interactive session, runs a Python |
| 8 | # interpreter, and replays all the inputs from the log, checking that the |
| 9 | # outputs all match the log. This allows us to easily test behavior and |
| 10 | # document functions at the same time, since the log shows exactly how functions |
| 11 | # are called and what their outputs look like. See |
| 12 | # http://www.python.org/doc/2.4.3/lib/module-doctest.html for more details. |
| 13 | |
| 14 | # In this file, we run doctest on all files found in the doctests/ directory. |
| 15 | # We use django.test.utils to run the tests against a fresh test database every |
| 16 | # time. |
| 17 | |
showard | 2e490cc | 2008-10-08 19:15:45 +0000 | [diff] [blame] | 18 | class DoctestRunner(object): |
| 19 | _PRINT_AFTER = 'Ran %d tests from %s' |
mbligh | e8819cd | 2008-02-15 16:48:40 +0000 | [diff] [blame] | 20 | |
showard | 2e490cc | 2008-10-08 19:15:45 +0000 | [diff] [blame] | 21 | def __init__(self, app_dir, app_module_name): |
| 22 | self._app_dir = app_dir |
| 23 | self._app_module_name = app_module_name |
showard | 5c7e819 | 2008-04-08 19:43:21 +0000 | [diff] [blame] | 24 | |
mbligh | e8819cd | 2008-02-15 16:48:40 +0000 | [diff] [blame] | 25 | |
showard | 2e490cc | 2008-10-08 19:15:45 +0000 | [diff] [blame] | 26 | def _get_doctest_paths(self): |
| 27 | doctest_dir = os.path.join(self._app_dir, 'doctests') |
| 28 | doctest_paths = [os.path.join(doctest_dir, filename) for filename |
| 29 | in os.listdir(doctest_dir) |
| 30 | if not filename.startswith('.') |
| 31 | if not filename.endswith('~')] |
| 32 | return sorted(doctest_paths) |
mbligh | e8819cd | 2008-02-15 16:48:40 +0000 | [diff] [blame] | 33 | |
| 34 | |
showard | 2e490cc | 2008-10-08 19:15:45 +0000 | [diff] [blame] | 35 | def _get_modules(self): |
| 36 | modules = [] |
| 37 | module_names = [os.path.basename(filename)[:-3] |
| 38 | for filename |
| 39 | in glob.glob(os.path.join(self._app_dir, '*.py')) |
| 40 | if '__init__' not in filename |
| 41 | and 'test.py' not in filename] |
| 42 | # TODO: use common.setup_modules.import_module() |
| 43 | app_module = __import__(self._app_module_name, globals(), locals(), |
| 44 | module_names) |
| 45 | for module_name in module_names: |
| 46 | modules.append(getattr(app_module, module_name)) |
| 47 | return modules |
| 48 | |
| 49 | |
| 50 | def run_tests(self): |
| 51 | """ |
| 52 | module_list is ignored - we're just required to have this signature as a |
| 53 | Django test runner. |
| 54 | """ |
| 55 | doctest_paths = self._get_doctest_paths() |
| 56 | modules = self._get_modules() |
| 57 | total_errors = 0 |
Mike Truty | 3536b98 | 2011-08-29 13:05:16 -0700 | [diff] [blame] | 58 | old_db = settings.DATABASES['default']['NAME'] |
showard | 2e490cc | 2008-10-08 19:15:45 +0000 | [diff] [blame] | 59 | django.test.utils.setup_test_environment() |
showard | a5288b4 | 2009-07-28 20:06:08 +0000 | [diff] [blame] | 60 | connection.creation.create_test_db() |
showard | 2e490cc | 2008-10-08 19:15:45 +0000 | [diff] [blame] | 61 | try: |
| 62 | for module in modules: |
| 63 | failures, test_count = doctest.testmod(module) |
| 64 | print self._PRINT_AFTER % (test_count, module.__name__) |
| 65 | total_errors += failures |
| 66 | for path in doctest_paths: |
| 67 | failures, test_count = doctest.testfile(path, |
| 68 | module_relative=False) |
| 69 | print self._PRINT_AFTER % (test_count, path) |
| 70 | total_errors += failures |
| 71 | finally: |
showard | a5288b4 | 2009-07-28 20:06:08 +0000 | [diff] [blame] | 72 | connection.creation.destroy_test_db(old_db) |
showard | 2e490cc | 2008-10-08 19:15:45 +0000 | [diff] [blame] | 73 | django.test.utils.teardown_test_environment() |
| 74 | print |
| 75 | if total_errors == 0: |
| 76 | print 'OK' |
| 77 | else: |
| 78 | print 'FAIL: %d errors' % total_errors |
| 79 | return total_errors |