I am using DRF and the tests are written for the APIs. I want to run those test on heroku and also use the CI in my pipeline for the development environment.
When default SQLlite db is used in the config, the error that I am getting -
Normally Django will use a connection to the 'postgres' database to avoid running initialization queries against the production database when it's not needed (for example, when running tests). Django was unable to create a connection to the 'postgres' database and will use the first PostgreSQL database instead.
My code and configs
test_*.py
class TestUser(APITestCase):
def setUp(self):
...
def test_user(self):
...
base.py file
db_config = dj_database_url.config(conn_max_age=600, ssl_require=False)
DATABASES_AVAILABLE = {
'test': db_config,
'sqlite': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
}
database = os.environ.get('DJANGO_DATABASE_TEST', 'sqlite')
DATABASES = {
'default': DATABASES_AVAILABLE[database]
}
# Database Configuration Ends
django_heroku.settings(locals())
In Heroku CI Configs, I have
DJANGO_DATABASE_TEST : test
app.json
{
"buildpacks": [{ "url": "heroku/python" }],
"environments": {
"test": {
"env": { "POSTGRESQL_VERSION": "10" },
"addons": ["heroku-postgresql:in-dyno"],
"scripts": {
"test": "./manage.py migrate && ./manage.py test"
}
}
}
}
django.db.utils.OperationalError: server does not support SSL, but SSL was required
django_heroku.settings(locals())
db_config = dj_database_url.config(conn_max_age=600, ssl_require=False)
DATABASES_AVAILABLE = {
'test': db_config,
'sqlite': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
}
database = os.environ.get('DJANGO_DATABASE_TEST', 'sqlite')
DATABASES = {
'default': DATABASES_AVAILABLE[database]
}
if I move django_heroku.settings(locals(), databases=True)
before the DATABASE
then I am getting this error
psycopg2.errors.UndefinedObject: role "postgres" does not exist
After a lot of experiments and reading, I have a solution
created different environments files in Django - develop
, productions
, ci
.
In the ci
environment i did not include django_heroku.settings(locals())
and only added the following configurations
DEBUG = True
APPEND_SLASH = True
SECURE_SSL_REDIRECT = False
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'postgres_buildpack_db',
}
}
and in the app.json file
{
"buildpacks": [{ "url": "heroku/python" }],
"environments": {
"test": {
"env": { "POSTGRESQL_VERSION": "10" },
"addons": ["heroku-postgresql:in-dyno"],
"scripts": {
"test-setup": "./manage.py migrate && ./manage.py createsuperuser --noinput --username='admin' --email='admin@admin.com'",
"test": "./manage.py migrate"
}
}
}
}
django_heroku.settings(locals())
is setting the Db SLL connection to true, and indyno db does not support SSL, so removed it in in CI env.
Finally all the tests ran in the Heroku-CI. Phew!