Wednesday, March 27, 2013

Re: Testing with a custom user model as a ForeignKey in Django 1.5

2013/3/18 Felipe Coelho <fcoelho.9@gmail.com>
 1) Using tests that need the models, but don't actually touch the database. This means you can put the model definition inline in the test code, so AUTH_USER_MODEL has the right value when the code is run. This lets us test validation conditions, etc, but not hit the database. You *might* be able to get away with manually running syncdb in the middle of the test -- Django's swappable_model test contains an example of doing this, but only for the purposes of recreating permissions, not tables. 

The issue is that I'm trying to port an application with a whole test suite to work with custom user models, so I've got many tests which make use of classes like ModelWithForeign already.
 
 2) Define 2 "ModelWIthForeign" classes, and use the "right" one depending on what the User model is at the time of test. This works fine for Django's purposes because "ModelWithForeign" is a test-only model, so it doesn't matter if you have a few of them. This approach won't be successful if you're actually shipping ModelWithForeign as a core part of your system.

 3) Use test decorators to skip the test if a non-default user model is in use.

The issue really is that I'm using ModelWithForeign in here, but the real app has one class with a ForeignKey to the user model as well. I can certainly skip the tests which use that model or which touch the database, but since this is a user registration app, being able to test it with other user types is quite a requirement for me.
 
Any suggestions on how to improve Django's testing infrastructure to handle custom User models would be gratefully accepted (especially if they come with patches). It's still new code, so reports of problems like yours are helpful in shaping what features we've missed during initial development.

I don't have any knowledge on the inside of Django, but if I figure out something, I'll certainly share it and try to create a patch for it.

Currently I'm running the test suite using a runtests.py file like this one, and I'm thinking of two possible "solutions":
  • Making the runtests.py configure the system with different AUTH_USER_MODEL values each time, in a way that would run the tests multiple times, each time with a different database layout. The test suite would be in charge of creating the database each time, but since I can't call settings.configure multiple times, I somehow have to "unload" it before moving on to the next test group. This also has the disadvantage that, if built into my runtests.py, running the test suite when the app is installed in a larger project, only the tests running on the project-specified value for AUTH_USER_MODEL would run.
  • Maybe I could use multiple databases. In each one, the ForeignKey would be attached to a different user model, and then different databases could be selected depending on the currently defined user model. I don't know if that is possible, though.
Hi, just a follow up. I had this on StackOverflow as well but didn't get any answers there, so I just posted the method I'm currently using. Essentially, I'm launching a different process for each user model, in a way that I don't have to deal with user model changes, I just accept them as they are and continue testing. More details: http://stackoverflow.com/questions/15369987/testing-with-a-custom-user-model-as-a-foreignkey-in-django-1-5/15675119#15675119

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

No comments:

Post a Comment