I'm developing a simple Ajax backend that presently only consists of
one URLconf and a single view. I'm trying to do test-driven
development and have a few initial tests present, but 'manage.py test'
is crapping out on me.

Initially, I got ImproperlyConfiguredError for not having DATABASE_*
configured in the settings file. Googling this brought me to
http://docs.djangoproject.com/en/dev/topics/testing/#using-different-testing-frameworks
and Russell Keith-Magee's advice on the issue (e.g.
http://groups.google.com/group/django-users/browse_thread/thread/fe90a261293ea995
and 
http://groups.google.com/group/django-users/browse_thread/thread/d3cac9794c5e59f1
), suggesting creating a custom test runner by copying the code of the
default runner w/o the test database creation, and then defining
TEST_RUNNER in the settings file.

That's what I did, but a different set of errors appeared. First,
here's the code of my custom run_tests, with the database bits
commented out. (Based off trunk r9800)

- - - - -
import unittest
from django.conf import settings
from django.db.models import get_app, get_apps
from django.test.utils import setup_test_environment,
teardown_test_environment
from django.test.simple import build_suite, reorder_suite

def run_tests(test_labels, verbosity=1, interactive=True, extra_tests=
[]):
    """A copy of django.test.simple.run_tests with the test DB
creation commented out."""
    setup_test_environment()

    settings.DEBUG = False
    suite = unittest.TestSuite()

    if test_labels:
        for label in test_labels:
            if '.' in label:
                suite.addTest(build_test(label))
            else:
                app = get_app(label)
                suite.addTest(build_suite(app))
    else:
        for app in get_apps():
            suite.addTest(build_suite(app))

    for test in extra_tests:
        suite.addTest(test)

    suite = reorder_suite(suite, (TestCase,))

    # old_name = settings.DATABASE_NAME
    # from django.db import connection
    # connection.creation.create_test_db(verbosity, autoclobber=not
interactive)
    result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
    # connection.creation.destroy_test_db(old_name, verbosity)

    teardown_test_environment()

    return len(result.failures) + len(result.errors)

- - - - -

Given that, the correct TEST_RUNNER setting and nine tests to be run,
this is the output of ./manage.py test:

- - - - -
EEEEEEEEE
======================================================================
ERROR: Views should return HTTP 400 when receiving syntactically
invalid JSON as POST.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Python/2.5/site-packages/django/test/testcases.py",
line 238, in __call__
    self._pre_setup()
  File "/Library/Python/2.5/site-packages/django/test/testcases.py",
line 213, in _pre_setup
    self._fixture_setup()
  File "/Library/Python/2.5/site-packages/django/test/testcases.py",
line 410, in _fixture_setup
    if not settings.DATABASE_SUPPORTS_TRANSACTIONS:
  File "/Library/Python/2.5/site-packages/django/conf/__init__.py",
line 32, in __getattr__
    return getattr(self._target, name)
AttributeError: 'Settings' object has no attribute
'DATABASE_SUPPORTS_TRANSACTIONS'

[...same traceback reported eight more times, once per test...]
----------------------------------------------------------------------
Ran 0 tests in 0.002s

FAILED (errors=9)

- - - - -

Googling the issue, I stumbled across changeset 9756 (
http://code.djangoproject.com/changeset/9756 ) which appears to
introduce the DATABASE_SUPPORTS_TRANSACTIONS setting. Thinking it
might have introduced a bug, I tried running the tests against trunk
r9755. This is what happened then with ./manage.py test:

[...]
ImportError: cannot import name reorder_suite

reorder_suite was apparently introduced between r9755 and r9800, so I
took out the import and replaced my custom run_tests to be based off
r9755 (copy verbatim, comment out the DB bits just like before) and
ran ./manage.py test once more. This is the result:

- - - - - - -

EEEEEEEEE
======================================================================
ERROR: Views should return HTTP 400 when receiving syntactically
invalid JSON as POST.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Python/2.5/site-packages/django/test/testcases.py",
line 207, in __call__
    self._pre_setup()
  File "/Library/Python/2.5/site-packages/django/test/testcases.py",
line 188, in _pre_setup
    call_command('flush', verbosity=0, interactive=False)
  File "/Library/Python/2.5/site-packages/django/core/management/
__init__.py", line 158, in call_command
    return klass.execute(*args, **options)
  File "/Library/Python/2.5/site-packages/django/core/management/
base.py", line 222, in execute
    output = self.handle(*args, **options)
  File "/Library/Python/2.5/site-packages/django/core/management/
base.py", line 351, in handle
    return self.handle_noargs(**options)
  File "/Library/Python/2.5/site-packages/django/core/management/
commands/flush.py", line 30, in handle_noargs
    sql_list = sql_flush(self.style, only_django=True)
  File "/Library/Python/2.5/site-packages/django/core/management/
sql.py", line 131, in sql_flush
    statements = connection.ops.sql_flush(style, tables,
connection.introspection.sequence_list())
  File "/Library/Python/2.5/site-packages/django/db/backends/
__init__.py", line 292, in sql_flush
    raise NotImplementedError()
NotImplementedError

[...same traceback reported eight more times, once per test...]
----------------------------------------------------------------------
Ran 0 tests in 0.016s

FAILED (errors=9)

- - - - - - -

...and this is the current, r9755-based custom run_tests method, the
same as before but without the code introduced between r9755 and now:

- - - - - - -

def run_tests(test_labels, verbosity=1, interactive=True, extra_tests=
[]):
    setup_test_environment()

    settings.DEBUG = False
    suite = unittest.TestSuite()

    if test_labels:
        for label in test_labels:
            if '.' in label:
                suite.addTest(build_test(label))
            else:
                app = get_app(label)
                suite.addTest(build_suite(app))
    else:
        for app in get_apps():
            suite.addTest(build_suite(app))

    for test in extra_tests:
        suite.addTest(test)

    # old_name = settings.DATABASE_NAME
    # from django.db import connection
    # connection.creation.create_test_db(verbosity, autoclobber=not
interactive)
    result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
    # connection.creation.destroy_test_db(old_name, verbosity)

    teardown_test_environment()

    return len(result.failures) + len(result.errors)

- - - - - - -

I went as far as commenting out all "django-specific" bits of the test
runner, removing the imports from django.* to make sure that run_tests
was just using the unittest functionality, and added a single test
manually to the suite variable, but the same NotImplementedError came
up. Looks like the empty DATABASE_* settings are causing something
somewhere in the chain to go to the BaseDatabaseOperations class and
call its methods, all of which of course return NotImplementedError.

This is now well beyond my skills, so I turn to you, the experts. What
is the correct method of creating a custom test runner for testing
Django without a database, and is this different pre- and post-r9756,
since at least the error message is completely different?

TIA,
Jarkko Laiho
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to