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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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:: | ||
|
||
from django.db import migrations | ||
from django.conf import settings | ||
|
||
|
||
def is_test_db(): | ||
return settings.DATABASES.get( | ||
'default', {}).get('NAME', '').startswith('test_') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm using sqlite and the DATABASES['default']['NAME'] was ':memory:'. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
There was a problem hiding this comment.
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
?There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.