Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to register Django models that are only used in tests

I'm writing an app that has a custom model field. I want to test that field, using a model that is only used within tests, but I'm struggling to get the model working in tests.

Some of my app structure is like this:

myapp/
    fields.py
    models.py
tests/
    fields/
        models.py
        tests.py
    settings.py
    test_models.py
    test_views.py

tests/fields/models.py is like this:

from django.db import models
from myapp.fields import MyCustomField

class MyTestModel(models.Model):
    custom_field = MyCustomField()

I then import MyTestModel and try to use it in tests/fields/tests.py.

Things I've tried...

1. Initially I got:

RuntimeError: Model class tests.fields.models.MyTestModel doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

2. So I added "tests", to INSTALLED_APPS in tests/settings.py. But then I get:

django.db.utils.OperationalError: no such table: tests_mytestmodel

3. I've seen this in the docs about isolating model registration in tests. So I've tried moving the models into tests/fields/tests.py:

from django.db import models
from django.test import TestCase
from django.test.utils import isolate_apps
from myapp.fields import MyCustomField

@isolate_apps('tests')
class MyTestCase(TestCase):

    def test_things_work(self):
        class MyTestModel(models.Model):
            custom_field = MyCustomField()

        obj = MyTestModel.objects.create(custom_field='foo')
        self.assertEqual(...)

But that still gets me:

django.db.utils.OperationalError: no such table: tests_mytestmodel

I've tried looking through the tests of lots of other Django projects that provide custom fields and can't see what I'm missing that (apparently) makes their tests with models work.

It sounds like, somehow, there need to be migrations for these models that are only used in the tests... is that right? How? Or something else?

like image 258
Phil Gyford Avatar asked Mar 14 '17 13:03

Phil Gyford


People also ask

How do you write test cases for models in Django?

To write a test you derive from any of the Django (or unittest) test base classes (SimpleTestCase, TransactionTestCase, TestCase, LiveServerTestCase) and then write separate methods to check that specific functionality works as expected (tests use "assert" methods to test that expressions result in True or False values ...

Should I test Django models?

If the code in question is built into Django, don't test it. Examples like the fields on a Model or testing how the built-in template. Node renders included tags. If your model has custom methods, you should test that, usually with unit tests.


1 Answers

Since your test app is in a nested folder you need to specify the whole path to it in INSTALLED_APPS instead of the parent folder, like:

INSTALLED_APPS = [
    ...,
    "tests.fields"
]
like image 81
djangonaut Avatar answered Oct 14 '22 23:10

djangonaut