pytest-django
pytest-django copied to clipboard
Create models with managed = False
I have a project that works with 3rd party database, all the models for that database have managed = False in Meta because I don't want them to be created in my db.
I would still like to run some tests with fake data. So my question is: is there any way to create unmanaged models only for testing?
I tried to find something that would let me test unmanaged models, and only found solutions for default django testing, nothing that would work with pytest-django. So I hacked a marker with signature pytest.mark.django_use_model(model) that creates model (or models) for the scope of marker ignoring the managed = False. @pelme do you think there is a chance that such gizmo belongs to pytest-django? I already have tests for this, but if it doesn't belong here I won't bother with updating documentation but will create it as standalone plugin instead. If it can be merged to pytest-django, I think it would make sense to make it that test units marked with django_use_model would not require django_db, I'm not sure how to accomplish that.
It's here: https://github.com/ojake/pytest-django/tree/unmanaged_model
Cheers.
I think it would be useful.
But it makes sense to require the DB marker, since it will hit/use the database. Or are you referring to skipping the setup part of it?
For reference: https://docs.djangoproject.com/en/1.8/ref/models/options/#django.db.models.Options.managed.
Anyway, it would be possible to automatically include / require another fixture/marker with yours.
Hey. Currently it has to be:
@pytest.mark.django_db
@pytest.mark.django_use_model(MyUnamanged)
def test_myunmanaged_model():
...
My thinking was that it's kind of imperative that if test uses model, it will most likely hit db, so django_db could be omitted, but maybe it's better to keep it explicit.
While I like the explicit approach (which could be used as a marker), it can be included (see _live_server_helper
, https://github.com/pytest-dev/pytest-django/blob/master/pytest_django/fixtures.py#L350-L351):
request.getfuncargvalue('db')
But then it might request/use db
, when transactional_db
is requested explicitly - not sure?!
A test for this would be good.
old thread but figured I'd post my workaround, which is simple and not pytest specific.
I have different settings modules for staging, prod, unittests etc but same result could be achieved using env variables or command line opts
In some models.py:
MANAGED = settings.AM_I_TESTING # Any logic/hard code that designates we're testing
class SomeModel(Model):
class Meta:
managed = MANAGED
I found an elegant solution (or workaround?). Some undocumented feature of django probably. For your unmanaged models you need to create a dedicated app and you have to remove migrations folder and do not generate any migrations. The app has to have the same name as the db alias in settings.DATABASES. Then it will automatically create the models for you. Reference only in source of django: https://github.com/django/django/blob/06d34aab7cfb1632a1538a243db81f24498525ff/django/core/management/commands/migrate.py#L198
this works for me with django 2.2 and latest pytest
P.S. you also need to have a custom router which will map app labels to the same-named DBs.
details here https://stackoverflow.com/a/38446760/611677
thanks