Best way to change the "settings" value from a Python test case?

I am writing unit tests in Python for the first time, for a Django application. I ran into a problem. To test specific functionality, I need to change the value of one of the application settings. Here is my first attempt:

def test_in_list(self): mango.settings.META_LISTS = ('tags',) tags = Document(filepath).meta['tags'] self.assertEqual(tags, [u'Markdown', u'Django', u'Mango']) 

What I'm trying to do is change the META_LISTS value so that the new value is used when creating the Document object. Corresponding imports ...

 # tests.py from mango.models import Document import mango.settings # models.py from mango.settings import * 

If I understood correctly, since models.py already imported names from mango.settings , changing the value of META_LISTS inside mango.settings will not change the value of META_LISTS inside mango.models .

Perhaps - perhaps even that I am completely wrong about this. What is the correct way to change the value of such a “setting” from a test case?

Edit: I did not mention that the models.py file contains vanilla Python classes, not Django models. I definitely need to rename this file!

+4
source share
4 answers

In models.py use import mango.settings . Then you can set the variable in your test code, like any other:

 mango.settings.foo = 'bar' 

The module is singleton. You can change the values ​​in your namespace from anywhere in your code.

But this will not work if you use from mango.settings import * , as this expression copies the values ​​in the module into the current namespace.

+5
source

Will this setting be used during tests? In this case, one solution would be to create a settings file for testing. E.g. add settings_for_tests.py .

 # settings_for_tests.py from settings import * # Get everything from default settings file. # Override just what is required. META_LISTS = ('tags',) 

And then run your tests like this:

 $ python ./manage.py test mango --settings=settings_for_tests 

This will ensure that models are created in the test database using test parameters, rather than default settings.

If you do this, it makes sense to move the configuration files inside the directory. For instance,

 project | |_ settings | | | |_ __init__.py # Contains merely from settings import * | |_ settings.py | |_ settings_for_tests.py | |_ apps | 
+2
source

To change the settings in TestCases I use a modified version of this fragment http://www.djangosnippets.org/snippets/1011/

Here is my modification of this snippet http://github.com/dominno/django-moderation/blob/master/src/moderation/tests/utils/testsettingsmanager.py

Then I create a file with my test settings, and then I use (example from my project):

 class SerializationTestCase(SettingsTestCase): fixtures = ['test_users.json', 'test_moderation.json'] test_settings = 'moderation.tests.settings.generic' def setUp(self): self.user = User.objects.get(username='moderator') self.profile = UserProfile.objects.get(user__username='moderator') def test_serialize_of_object(self): """Test if object is propertly serialized to json""" json_field = SerializedObjectField() self.assertEqual(json_field._serialize(self.profile), '[{"pk": 1, "model": "test_app.userprofile", "fields": '\ '{"url": "http://www.google.com", "user": 1, '\ '"description": "Old description"}}]', ) 

It will track the original settings and easily return them when the test is complete.

+2
source

There is an easier way to do this.

Use multiple configuration files - each under the right configuration control.

We doing this.

  • We have the main settings module, which has the "always applies" settings. Middleware, installed applications, other settings unique to our applications.

  • We have settings for the “subclass”, which (a) import the main settings, and then (b) enter the specifics for a specific platform (or specific for a particular scene or defined by the client) settings. Here we isolate our path to the Windows file. In addition, the location of static media files. Plus customer template templates, etc.

  • We break our test scripts into several parts. "Default" tests.py performs basic tests of the model, form and presentation, which should work on all platforms, at all stages of development (dev, test, qa, etc.) and all clients.

  • We have separate unit test scripts that require special settings for particularly complex fixtures. They are not in tests.py and do not start automatically. They require explicit calling of Django utilities to install and test test environments.

See http://docs.djangoproject.com/en/1.2/topics/testing/#module-django.test.utils


how would you recommend testing a stupid function that returns "hello" when a particular setting is true, and "goodbye" when false

This may be a sign of poor construction. Test-Driven Design (TDD) assumes that you should have designed it so that it can be tested without a complicated setup.

If you have to do this through settings, what are you really doing? What parameter values ​​propagate in your code? This is silly. You must believe that the structure works. In fact, you should assume that the framework works, otherwise you must test each function of the framework.

You should have a function that takes settings.SOME_SETTING as an argument so that you can test it as a standalone unit without fuss in order to properly fix the whole environment. You must believe that the environment and infrastructure really work.

+1
source

All Articles