Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trac #7835: Test only models doc #4700

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs/topics/testing/advanced.txt
Expand Up @@ -307,6 +307,53 @@ running your tests, you can define test-only models in its ``models.py``
file.


Test-only models
==========================================================

Test-only models are models that are only created while running unit tests. This is particularly useful when writing :doc:`reusable applications </intro/reusable-apps>` that do not contain any models of their own.

Consider the following structure::

polls/
migrations/
0001_initial.py
__init__.py
tests/
__init__.py
models.py
test_polls.py
...
__init__.py
models.py
views.py
urls.py
...

The ``models.py`` file in the test module contains your test-only model definitions. It is important to leave the original ``models.py`` file in the app module even if it is empty.

Create a migration for your test-models in the migrations module. You will need to adapt the migration to only execute during unit tests. You can do this by checking the database name::

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by creating the migration in the migrations module? Are you saying put it in migrations/__init__.py?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create the migration (python file) inside the migrations folder just like any other migration. e.g polls/migrations/0002_add_test_models.py

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, so you're saying to create a normal migration in the migration chain, but with the conditional that prevents migration except in tests.so in your example, 0002_add_test_models.py would depend on the previous 0001 migration and the subsequent 0003 migration would depend on 0002_add_test_models. And inevitably this migration would be squashed into the others.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 0002 will go into the migration chain after 0001 and before 0003. In the normal migration sequence, it will essentially be a noop ("no operation") because the real database will not start with 'test_'. In the migration sequence during unit tests however, the database will start with 'test_' and therefore migration 0002 will actually run and create tables for your test models.

I am not sure about what effect squashing migrations will have on this.


from django.db import migrations
from django.conf import settings


def is_test_db():
return settings.DATABASES.get(
'default', {}).get('NAME', '').startswith('test_')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using sqlite and the DATABASES['default']['NAME'] was ':memory:'.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't comment specifically about what Django does with SQLite in memory databases. I am just going from what the documentation says on database naming here https://docs.djangoproject.com/en/1.8/topics/testing/overview/#the-test-database

I have only ever used this technique on a postgres database.


class Migration(migrations.Migration):

dependencies = []

if is_test_db():
operations = [
migrations.CreateModel(...),
...
]

That's it! The test-models will now be usable in your unit tests.


.. _other-testing-frameworks:

Using different testing frameworks
Expand Down