We don’t strictly require 100% test coverage (yet), but we aim to have:

  • >70% coverage.
  • Unit tests for all regression bugs.
  • Unit or integration tests for complex, fragile, or important functionality.

GLAMkit uses a custom script runtests.sh to run tests, which configures the test database and restores from test_initial_data.sql if available, to speed up migrations.

Running tests

Run GLAMkit tests

runtests.sh path/to/icekit/

Run specific tests

runtests.sh foo.bar:Baz.test_foo

Discover tests in the current folder and run without migrations:

runtests.sh -n .

Speed up test running

QUICK=1 runtests.sh ...

This reuses the test databases, and skips the collectstatic step – you’ll need to populate a test database and run collectstatic beforehand.

Working with the database for tests

Creating migrations for a test model

BASE_SETTINGS_MODULE=test manage.py makemigrations

Opening an interactive shell to inspect the test database

BASE_SETTINGS_MODULE=test manage.py shell_plus

Creating a data dump with migrations applied

The slowest part of running tests from scratch is usually the “Rendering Model States...” stage of migrations. This can be speeded up by loading a pre- migrated database dump. GLAMkit’s runtests.sh automatically uses a file called test_initial_data.sql.

To create a data dump called test_initial_data.sql with migrations applied:

  1. Drop/recreate your test database:

    dropdb FOO_test_develop
    createdb FOO_test_develop
  2. Run migrations:

    BASE_SETTINGS_MODULE=test manage.py migrate
  3. Dump the database to test_initial_data.sql:

    pg_dump -O -x -f test_initial_data.sql -d test_FOO_develop
    git add test_initial_data.sql

Creating fluent pages in tests

You can create fluent pages efficiently using django-dynamic-fixture:

from django.contrib.auth import get_user_model
from django_webtest import WebTest
from django_dynamic_fixture import G
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from icekit.models import Layout
from icekit.page_types.layout_page.models import LayoutPage

User = get_user_model()

class FluentPageTestCase(WebTest):
    def setUp(self):
        self.layout_1 = G(
        self.staff_1 = User.objects.create(
        self.page_1 = LayoutPage.objects.create(
            title='Test Page',
            status='p',  # Publish the page

There is also a helper function to add content items:

from icekit.utils.fluent_contents import create_content_instance

    self.child_page_1 = create_content_instance(
        placeholder_name="main", # default
        **kwargs # arguments for initialising the ContentItem model