Mercurial > nosedjango
annotate nosedjango/nosedjango.py @ 5:22ae9aa457af
excercise more bits of the django 1.0b1 test framework
author | Victor Ng <victor@monkeybean.ca> |
---|---|
date | Thu, 28 Aug 2008 11:29:21 -0400 |
parents | b761c26773a3 |
children | dfba3a3a4343 |
rev | line source |
---|---|
0 | 1 """ |
2 nose plugin for easy testing of django projects and apps. Sets up a test | |
3 database (or schema) and installs apps from test settings file before tests | |
4 are run, and tears the test database (or schema) down after all tests are run. | |
5 """ | |
6 | |
7 import os, sys | |
8 import re | |
9 | |
10 from nose.plugins import Plugin | |
11 import nose.case | |
12 | |
13 # Force settings.py pointer | |
14 # search the current working directory and all parent directories to find | |
15 # the settings file | |
16 from nose.importer import add_path | |
17 os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' | |
5
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
18 import re |
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
19 NT_ROOT = re.compile(r"^[a-zA-Z]:\\$") |
0 | 20 def get_SETTINGS_PATH(): |
5
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
21 ''' |
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
22 Hunt down the settings.py module by going up the FS path |
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
23 ''' |
0 | 24 cwd = os.getcwd() |
25 while cwd: | |
26 if 'settings.py' in os.listdir(cwd): | |
27 break | |
28 cwd = os.path.split(cwd)[0] | |
5
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
29 if os.name == 'nt' and NT_ROOT.match(cwd): |
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
30 return None |
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
31 elif cwd == '/': |
0 | 32 return None |
33 return cwd | |
5
22ae9aa457af
excercise more bits of the django 1.0b1 test framework
Victor Ng <victor@monkeybean.ca>
parents:
3
diff
changeset
|
34 |
0 | 35 SETTINGS_PATH = get_SETTINGS_PATH() |
36 | |
37 | |
38 class NoseDjango(Plugin): | |
39 """ | |
40 Enable to set up django test environment before running all tests, and | |
41 tear it down after all tests. If the django database engine in use is not | |
42 sqlite3, one or both of --django-test-db or django-test-schema must be | |
43 specified. | |
44 | |
45 Note that your django project must be on PYTHONPATH for the settings file | |
46 to be loaded. The plugin will help out by placing the nose working dir | |
47 into sys.path if it isn't already there, unless the -P | |
48 (--no-path-adjustment) argument is set. | |
49 """ | |
50 name = 'django' | |
51 | |
52 def configure(self, options, conf): | |
53 Plugin.configure(self, options, conf) | |
54 self.verbosity = conf.verbosity | |
55 | |
56 def begin(self): | |
57 """Create the test database and schema, if needed, and switch the | |
58 connection over to that database. Then call install() to install | |
59 all apps listed in the loaded settings module. | |
60 """ | |
61 # Add the working directory (and any package parents) to sys.path | |
62 # before trying to import django modules; otherwise, they won't be | |
63 # able to find project.settings if the working dir is project/ or | |
64 # project/.. | |
65 | |
66 if not SETTINGS_PATH: | |
67 sys.stderr.write("Can't find Django settings file!\n") | |
68 # short circuit if no settings file can be found | |
69 return | |
70 | |
71 if self.conf.addPaths: | |
72 map(add_path, self.conf.where) | |
73 | |
74 add_path(SETTINGS_PATH) | |
75 sys.path.append(SETTINGS_PATH) | |
76 import settings | |
77 settings.DEBUG = False # I have no idea why Django does this, but it does | |
78 from django.core import mail | |
79 self.mail = mail | |
80 from django.conf import settings | |
81 from django.core import management | |
82 from django.test.utils import setup_test_environment | |
83 from django.db import connection | |
84 | |
85 self.old_db = settings.DATABASE_NAME | |
86 | |
87 # setup the test env for each test case | |
88 setup_test_environment() | |
89 connection.creation.create_test_db(verbosity=self.verbosity) | |
90 | |
91 # exit the setup phase and let nose do it's thing | |
92 | |
93 def beforeTest(self, test): | |
94 | |
95 if not SETTINGS_PATH: | |
96 # short circuit if no settings file can be found | |
97 return | |
98 | |
99 from django.core.management import call_command | |
100 call_command('flush', verbosity=0, interactive=False) | |
101 | |
102 if isinstance(test, nose.case.Test) and \ | |
103 isinstance(test.test, nose.case.MethodTestCase) and \ | |
104 hasattr(test.context, 'fixtures'): | |
105 # We have to use this slightly awkward syntax due to the fact | |
106 # that we're using *args and **kwargs together. | |
107 call_command('loaddata', *test.context.fixtures, **{'verbosity': 0}) | |
108 self.mail.outbox = [] | |
109 | |
110 def finalize(self, result=None): | |
111 """ | |
112 Clean up any created database and schema. | |
113 """ | |
114 if not SETTINGS_PATH: | |
115 # short circuit if no settings file can be found | |
116 return | |
117 | |
118 from django.test.utils import teardown_test_environment | |
119 from django.db import connection | |
120 connection.creation.destroy_test_db(self.old_db, verbosity=self.verbosity) | |
121 teardown_test_environment() |