How to set up Django tests to use a free PostgreSQL database in Heroku
Test with a database close to production configuration
Sqlite databases are great for testing purposes, they are fast and don’t need much setup, but when your Django app grows, you will need to test in an environment similar to production to spot as much errors as possible.
This guide assumes you have a Django app hosted at Heroku working with a PostgreSQL database add-on in production.
We are going to use PostgreSQL Hobby dev plan to get a free database just for testing against it.
This can be thought as a previous step to use a Continuous Integration service.
For example, for an app I am currently developing, tests summary passed from this (using sqlite):
Ran 251 tests in 294.559s
FAILED (failures=2, skipped=18)
Destroying test database for alias 'default'...
to this (using postgresql):
----------------------------------------------------------------------
Ran 249 tests in 1882.815s
FAILED (failures=1, errors=70, skipped=18)
Preserving test database for alias 'default'...
1. Create testing DB in Heroku
To create the database: heroku addons:create heroku-postgresql:hobby-dev
.
2. Get credentials
Get the credentials using the above database color e.g.: heroku pg:credentials:url HEROKU_POSTGRESQL_BRONZE
$ heroku pg:credentials:url HEROKU_POSTGRESQL_BRONZE
Connection info string:
"dbname=d1jjjjjjj23b host=ec2-54-225-222-121.compute-1.amazonaws.com port=5432 user=myuser password=hash sslmode=require"
Connection URL:
postgres://myuser:hash@ec2-54-225-222-121.compute-1.amazonaws.com:5432/d1jjjjjjj23b
Pay attention to the above database user and connection url as we will use it in the following steps.
3. Configure Django db settings
In the DATABASE
section of yourapp/settings.py
, set the
DATABASES['TEST']['NAME']
key with the database name of the new db, e.g. d1jjjjjjj23b
:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'TEST': {
'NAME': 'd1jjjjjjj23b',
},
}
}
# Heroku: Update database configuration from $DATABASE_URL.
import dj_database_url
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)
Note the usage of the package:
https://github.com/kennethreitz/dj-database-url to get the database
connection settings from an environment variable DATABASE_URL
4. Run tests with DATABASE_URL env variable
Set the env variable when running the test, and specify to not create the database (Heroku already created it):
DATABASE_URL="postgres://myuser:hash@ec2-54-225-222-121.compute-1.amazonaws.com:5432/d1jjjjjjj23b" python manage.py test --keepdb
Now the test command will use the above database when running tests.
Possible Errors
If you don’t set the NAME
key for the testing database, then the
test
command will complain from being unable to create the database
with the message Got an error creating the test database: permission denied to create database
, that is why we also add the --keepdb
parameter to avoid the testing command to try to create the database again:
$ DATABASE_URL="postgres://myuser:hash@ec2-54-225-222-121.compute-1.amazonaws.com:5432/d1jjjjjjj23b" python manage.py test
Creating test database for alias 'default'...
/home/marcanuy/.virtualenvs/myapp/lib/python3.6/site-packages/django/db/backends/postgresql/base.py:269: RuntimeWarning: 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.
RuntimeWarning
Got an error creating the test database: permission denied to create database
References
- https://docs.djangoproject.com/en/2.1/ref/databases/
- https://docs.djangoproject.com/en/2.1/topics/testing/
- https://docs.djangoproject.com/en/2.1/ref/settings/#std:setting-DATABASE-TEST
- https://docs.djangoproject.com/en/2.1/ref/settings/#std:setting-NAME
- https://github.com/kennethreitz/dj-database-url
- August 1, 2023
- How to create a reusable Django app and distribute it with PIP or publish to pypi.orgJune 29, 2021
- How To Serve Multiple Django Applications with uWSGI and Nginx in Ubuntu 20.04October 26, 2020
- How to add favicon to Django in 4 stepsSeptember 3, 2020
- Categories in Django with BreadcrumbsAugust 30, 2020
- How To Migrate From SQLite To PostgreSQL In Django In 3 stepsAugust 28, 2020
- Practical guide to internationalize a Django app in 5 steps.August 24, 2020
- Disable new users singup when using Django's allauth packageSeptember 3, 2019
- How to add ads.txt to Django as requested by Google AdsenseAugust 30, 2019
- Have multiple submit buttons for the same Django formJuly 2, 2019
- Better Testing with Page Object Design in DjangoMay 1, 2019
- Generating slugs automatically in Django without packages - Two easy and solid approachesFebruary 14, 2019
- How to set up Django tests to use a free PostgreSQL database in Heroku
- Dynamically adding forms to a Django FormSet with an add button using jQueryFebruary 6, 2019
- Use of Django's static templatetag in css file to set a background imageFebruary 1, 2019
- Activate Django's manage.py commands completion in Bash in 2 stepsJanuary 29, 2019
- Sending Emails with Django using SendGrid in 3 easy stepsJanuary 9, 2019
- Adding Users to Your Django Project With A Custom User ModelSeptember 21, 2018
- Setting Up A Factory For One To Many Relationships In FactoryboyApril 17, 2018
- Generate UML class diagrams from django modelsMarch 24, 2018
- Set Up Ubuntu To Serve A Django Website Step By StepJuly 3, 2017
- Django Project Directory StructureJuly 16, 2016
- How to Have Different Django Settings for Development and Production, and environment isolationJune 10, 2016
- Django OverviewJune 2, 2016
Django Forms
- Adding a Cancel button in Django class-based views, editing views and formsJuly 15, 2019
- Using Django Model Primary Key in Custom Forms THE RIGHT WAYJuly 13, 2019
- Django formset handling with class based views, custom errors and validationJuly 4, 2019
- How To Use Bootstrap 4 In Django FormsMay 25, 2018
- Understanding Django FormsApril 30, 2018
- How To Create A Form In DjangoJuly 29, 2016
Articles
Subcategories
Except as otherwise noted, the content of this page is licensed under CC BY-NC-ND 4.0 . Terms and Policy.
Powered by SimpleIT Hugo Theme
·