General issue: I have an abstract model that I want to test with a real model instance, however I don't want to have to completely restructure my project/test format. See these two answers for reference: First answer Second answer
I want to A) Define models inside each test app folder and not define them inside the actual apps B) Not have an additional/separate apps.py and settings.py configuration for each test folder. I know this is possible because the django project has a very similar test structure like this, but they use a test run script that I can't entirely decipher.
The test/ folder mirrors the app structure I have (which are blog/, projects/, richeditable/).
backend
├── projects
├── blog
├── richeditable
├── tests
│ ├── __init__.py
│ ├── conftest.py
│ ├── blog
│ │ ├── ...
│ ├── projects
│ │ ├── ...
│ └── richeditable
│ │ ├── __init__.py
│ │ ├── test_model.py
│ │ ├── models.py <-------------- This defines a model that inherits from richeditable.models
# richeditable/models.py
class Draftable(models.Model):
blah = models.IntegerField()
class Meta:
abstract = True
# tests/richeditable/models.py
class DummyDraftable(Draftable):
additional_field = models.BooleanField()
# class Meta:
# app_label = "some_app"
# ^--- Django does not seem to like having this blank and I don't know what to put to make this work
# tests/richeditable/test_model.py
import pytest
@pytest.fixture
def add_app(settings):
settings.INSTALLED_APPS += ['backend.tests.richeditable']
# presumably the above fixture would affect the apps/models
# settings before the database is created, but that does not seems to be the case
def test_please_work(add_app, db):
assert DummyDraftable.objects.create(blah=1, additional_field=True) is not None
My best guess from what I've seen of the django project script is that they load in each folder for testing as a module and add it to INSTALLED_APPS
at run time before the test cases. However, you can't just simply change INSTALLED_APPS
because models are being added and migrations have to be made to the test database beforehand as well as there seems to be a need to define an AppConfig
(because Django loses it's mind if you don't). I've tried to include the app_label
Meta field for models but it didn't work, or I may have done something wrong. But the point is, I don't see the script creating an AppConfig
and they somehow don't have to declare Meta
in their models.py
Pytest specific stuff:
Things get further complicated with pytest-django because it doesn't use Django's TestRunner
interface. This is how you would do it if that were the case (note the order of operations). I have already tried modifying the settings
pytest fixture before instantiating the db with the associated fixtures but this doesn't end up loading the module no matter what I do. From looking at the source code, it seems like the settings are fixed in place based on what the settings.py specifies and modifying the settings
fixture makes no difference to app loading.