Skip to content

Instantly share code, notes, and snippets.

@gregsadetsky
Last active May 28, 2021 18:37
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save gregsadetsky/5018173 to your computer and use it in GitHub Desktop.
Save gregsadetsky/5018173 to your computer and use it in GitHub Desktop.
See: http://stackoverflow.com/questions/13705328/ -- I was looking for a way to run Selenium tests for a Django app on a staging server hosted on Heroku using a PostgreSQL database. The DjangoTestSuiteRunner creates and destroys the whole database before/after testing, which would not work on Heroku where databases are added via other means (her…
import dj_database_url
TEST_DATABASES = {
'default': dj_database_url.config(env='TEST_DATABASE_URL')
}
# replace path below to point to HerokuTestSuiteRunner class
TEST_RUNNER = 'python.path.to.test_suite_runner.HerokuTestSuiteRunner'
"""
To use this, run:
heroku addons:add heroku-postgresql:dev
heroku config:set TEST_DATABASE_URL="postgres://..." # replace with the new HEROKU_POSTGRESQL_<COLOR>_URL
Then, make TEST_RUNNER setting a Python path to the HerokuTestSuiteRunner class.
"""
import django
from django.test.simple import DjangoTestSuiteRunner
from django.conf import settings
from django.core.management import call_command
from django.db.utils import ConnectionHandler
class HerokuTestSuiteRunner(DjangoTestSuiteRunner):
def setup_databases(self, **kwargs):
###
# WARNING: NOT handling 'TEST_MIRROR', 'TEST_DEPENDENCIES'
###
# get new connections to test database
test_connections = ConnectionHandler(settings.TEST_DATABASES)
for alias in django.db.connections:
test_connection = test_connections[alias]
# set django-wide connection to use test connection
django.db.connections[alias] = test_connection
# re-initialize database (this "replaces" the CREATE DATABASE which
# cannot be issued on Heroku)
cursor = test_connection.cursor()
cursor.execute('DROP SCHEMA public CASCADE')
cursor.execute('CREATE SCHEMA public')
# code below taken from
# django.test.simple.DjangoTestSuiteRunner.setup_databases and
# django.db.backends.creation.create_test_db
# make them tables
call_command('syncdb',
verbosity=0,
interactive=False,
database=test_connection.alias,
load_initial_data=False)
call_command('flush',
verbosity=0,
interactive=False,
database=test_connection.alias)
from django.core.cache import get_cache
from django.core.cache.backends.db import BaseDatabaseCache
for cache_alias in settings.CACHES:
cache = get_cache(cache_alias)
if isinstance(cache, BaseDatabaseCache):
call_command('createcachetable', cache._table,
database=test_connection.alias)
def teardown_databases(self, *args, **kwargs):
# NOP
pass
@nitochi
Copy link

nitochi commented Mar 12, 2013

Hi, thank you for your code! I'm getting this error on Heroku:

raise ImproperlyConfigured("You need to specify NAME in your Django settings file.")
django.core.exceptions.ImproperlyConfigured: You need to specify NAME in your Django settings file.

Copied your file and added this to settings:

TEST_DATABASES = {
'default': dj_database_url.config(env='TEST_DATABASE_URL')
}

TEST_RUNNER = 'test_tools.test_suite_runner.HerokuTestSuiteRunner'

added a test_tools module with test_suite_runner.py in it.

heroku config shows TEST_DATABASE_URL to the correct db.

Any ideas why?

@nitochi
Copy link

nitochi commented Mar 12, 2013

Nevermind...TEST_DATABASE_URL was improperly configured.

My confusion came from here:

heroku config:set TEST_DATABASE_URL="postgres://..." # replace with the new HEROKU_POSTGRESQL__URL

I added like this:

heroku config:set TEST_DATABASE_URL="postgres://HEROKU_POSTGRESQL_GOLD_URL"

Had to do heroku config

copied the HEROKU_POSTGRESQL_GOLD_URL value and changed it in TEST_DATABASE_URL...worked like a charm

@gregsadetsky
Copy link
Author

Hi @nitochi -- sorry I didn't see your comment. Your fix is correct.

Were you able to run your tests on Heroku?

Cheers

@jkevintu
Copy link

jkevintu commented Mar 3, 2016

See jazzband/django-nose#175

Usefrom django.test.runner import DiscoverRunner instead of
from django.test.simple import DjangoTestSuiteRunner

@Polidoro
Copy link

Polidoro commented Aug 8, 2016

A few minor changes for Django 1.9 (in addition to the change pointed out by jkevintu):

  • syncdb is deprecated and should be replaced with migrate
  • get_cache is deprecated, import caches instead, then replace get_cache(cache_alias) with caches[cache_alias]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment