Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm writing unit tests in Python for the first time, for a Django app. I've struck a problem. In order to test a particular piece of functionality, I need to change the value of one of the app's settings. Here's 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 value of META_LISTS such that the new value is used when the Document object is created. The relevant imports are...

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

# models.py
from mango.settings import *

If I've understood correctly, since models.py has already imported the names from mango.settings, changing the value of META_LISTS within mango.settings will not alter the value of META_LISTS within mango.models.

It's possible – likely even – that I'm going about this in completely the wrong way. What's the correct way to alter the value of such a "setting" from within a test case?

Edit: I failed to mention that the file models.py contains vanilla Python classes rather than Django models. I certainly need to rename this file!

like image 583
davidchambers Avatar asked Sep 30 '10 11:09

davidchambers


People also ask

How do you code a test case in Python?

First you need to create a test file. Then import the unittest module, define the testing class that inherits from unittest. TestCase, and lastly, write a series of methods to test all the cases of your function's behavior. First, you need to import a unittest and the function you want to test, formatted_name() .

How do I override Django settings?

The override_settings class can be used as either a class or method decorator or as a context manager to temporarily override the values of settings. After each test case has finished (when using it as a decorator) or after the context manager has exited, it resets the values in django.


2 Answers

In models.py, use import mango.settings. You can then set a variable in your test code like you would any other:

mango.settings.foo = 'bar'

A module is a singleton. You can change the values in its namespace from anywhere in your code.

But this won't work if you use from mango.settings import *, since that expression copies the values in the module into the current namespace.

like image 51
AndrewF Avatar answered Oct 20 '22 16:10

AndrewF


Will this setting be used throughout the tests? In that case one solution would be to create a settings file for testing. For e.g. add a 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 thus:

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

This will ensure that the models in the test database get created using the test settings and not the default settings.

If you are doing this it also makes sense to move the settings files inside a directory. For e.g.

project
  |
  |_ settings
  |    |
  |    |_ __init__.py # Contains merely from settings import *
  |    |_ settings.py
  |    |_ settings_for_tests.py
  |
  |_ apps
       |
like image 29
Manoj Govindan Avatar answered Oct 20 '22 17:10

Manoj Govindan