Merge lp:~zyga/django-testscenarios/0.6 into lp:django-testscenarios

Proposed by Zygmunt Krynicki
Status: Merged
Merged at revision: 23
Proposed branch: lp:~zyga/django-testscenarios/0.6
Merge into: lp:django-testscenarios
Diff against target: 431 lines (+160/-56)
15 files modified
django_testproject/settings.py (+16/-14)
django_testproject/templates/django_testproject/base.html (+10/-0)
django_testproject/templates/registration/base.html (+4/-0)
django_testproject/templates/registration/logged_out.html (+3/-0)
django_testproject/templates/registration/login.html (+25/-0)
django_testproject/tests.py (+50/-3)
django_testscenarios/__init__.py (+17/-0)
django_testscenarios/models.py (+1/-1)
django_testscenarios/test_project/__init__.py (+1/-1)
django_testscenarios/test_project/manage.py (+2/-2)
django_testscenarios/test_project/settings.py (+2/-6)
django_testscenarios/test_project/tests.py (+6/-2)
django_testscenarios/tests.py (+6/-6)
django_testscenarios/ubertest.py (+5/-6)
setup.py (+12/-15)
To merge this branch: bzr merge lp:~zyga/django-testscenarios/0.6
Reviewer Review Type Date Requested Status
Linaro Validation Team Pending
Review via email: mp+61984@code.launchpad.net

Description of the change

Fix design issue and release 0.6

The design issue was related to way django-testproject worked. It previously assumed that local test project would always have the name 'test_project'. This turned out to be a bad decision because of the way django double-imports settings with different paths. With simple scenario it could lead to wrong test_project being imported (different one in each python process).

To fix this I had to break backwards compatibility. There are few ways this affects users:

1) Instead of django_testproject.tests.run_tests() you must use django_testproject.tests.run_tests_for() and call it with the name of your settings module ("myapp.test_project.settings"). The old call is retained and works as before but is now deprecated.

2) To make it possible to import django_testscenarios.test_project directly I had to move some code from django_testproject/__init__.py into sub-module. This affects anyone who imported test cases from that package. They are all now in django_testscenarios.ubertest. This breaks compatibility directly.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'django_testproject/settings.py'
2--- django_testproject/settings.py 2011-01-04 09:24:44 +0000
3+++ django_testproject/settings.py 2011-05-23 14:59:46 +0000
4@@ -7,6 +7,9 @@
5 import django
6
7
8+DJANGO_TESTPROJECT_DIR = os.path.abspath(os.path.dirname(__file__))
9+
10+
11 def _get_default_settings(project_dir):
12 """
13 Produce default settings
14@@ -28,28 +31,27 @@
15 SITE_ID = 1
16 TEMPLATE_LOADERS = (
17 'django.template.loaders.filesystem.load_template_source',
18- 'django.template.loaders.app_directories.load_template_source',
19- )
20+ 'django.template.loaders.app_directories.load_template_source',)
21 TEMPLATE_DIRS = (
22- os.path.join(project_dir, "templates")
23- )
24+ os.path.join(project_dir, "templates"),
25+ os.path.join(DJANGO_TESTPROJECT_DIR, "templates"))
26 MIDDLEWARE_CLASSES = (
27 'django.middleware.common.CommonMiddleware',
28 'django.contrib.sessions.middleware.SessionMiddleware',
29 'django.contrib.auth.middleware.AuthenticationMiddleware',
30- 'django.middleware.transaction.TransactionMiddleware',
31- )
32+ 'django.middleware.transaction.TransactionMiddleware',)
33 if django.VERSION[0:2] >= (1, 2):
34 DATABASES = {
35 'default': {
36- 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
37- 'NAME': os.path.join(project_dir, 'test.db'), # Or path to database file if using sqlite3.
38- 'USER': '', # Not used with sqlite3.
39- 'PASSWORD': '', # Not used with sqlite3.
40- 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
41- 'PORT': '', # Set to empty string for default. Not used with sqlite3.
42- }
43- }
44+ # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
45+ 'ENGINE': 'django.db.backends.sqlite3',
46+ # Or path to database file if using sqlite3.
47+ 'NAME': os.path.join(project_dir, 'test.db'),
48+ 'USER': '', # Not used with sqlite3.
49+ 'PASSWORD': '', # Not used with sqlite3.
50+ 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
51+ 'PORT': '', # Set to empty string for default. Not used with sqlite3.
52+ }}
53 else:
54 DATABASE_ENGINE = 'sqlite3'
55 DATABASE_NAME = os.path.join(project_dir, 'test.db')
56
57=== added directory 'django_testproject/templates'
58=== added directory 'django_testproject/templates/django_testproject'
59=== added file 'django_testproject/templates/django_testproject/base.html'
60--- django_testproject/templates/django_testproject/base.html 1970-01-01 00:00:00 +0000
61+++ django_testproject/templates/django_testproject/base.html 2011-05-23 14:59:46 +0000
62@@ -0,0 +1,10 @@
63+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
64+<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE }}" xml:lang="{{ LANGUAGE_CODE }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
65+ <head>
66+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
67+ <title>{% block title %}{% endblock %}</title>
68+ </head>
69+ <body>
70+ {% block content %}{% endblock %}
71+ </body>
72+</html>
73
74=== added directory 'django_testproject/templates/registration'
75=== added file 'django_testproject/templates/registration/base.html'
76--- django_testproject/templates/registration/base.html 1970-01-01 00:00:00 +0000
77+++ django_testproject/templates/registration/base.html 2011-05-23 14:59:46 +0000
78@@ -0,0 +1,4 @@
79+{% extends "django_testproject/base.html" %}
80+
81+
82+{% block title %}Account management{% endblock %}
83
84=== added file 'django_testproject/templates/registration/logged_out.html'
85--- django_testproject/templates/registration/logged_out.html 1970-01-01 00:00:00 +0000
86+++ django_testproject/templates/registration/logged_out.html 2011-05-23 14:59:46 +0000
87@@ -0,0 +1,3 @@
88+{% block content %}
89+<p>You have been signed out</p>
90+{% endblock %}
91
92=== added file 'django_testproject/templates/registration/login.html'
93--- django_testproject/templates/registration/login.html 1970-01-01 00:00:00 +0000
94+++ django_testproject/templates/registration/login.html 2011-05-23 14:59:46 +0000
95@@ -0,0 +1,25 @@
96+{% extends "registration/base.html" %}
97+
98+
99+{% block title %}{{block.super }} | Sign in {% endblock %}
100+
101+
102+{% block header %}
103+{% if next %}
104+ <h1>You need to sign-in to access that page</h1>
105+{% else %}
106+ <h1>Sign in</h1>
107+{% endif %}
108+{% endblock %}
109+
110+
111+{% block content %}
112+<form method="post" action="{% url django.contrib.auth.views.login %}">
113+ {% csrf_token %}
114+ <p>{{ form.username }}</p>
115+ <p>{{ form.password }}</p>
116+ {{ form.errors }}
117+ <input id="id_submit" type="submit" value="Sign in with username and password" />
118+ <input type="hidden" name="next" value="{{ next }}" />
119+</form>
120+{% endblock %}
121
122=== modified file 'django_testproject/tests.py'
123--- django_testproject/tests.py 2011-01-19 11:02:44 +0000
124+++ django_testproject/tests.py 2011-05-23 14:59:46 +0000
125@@ -1,13 +1,52 @@
126+# Copyright (C) 2010, 2011 Linaro Limited
127+#
128+# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
129+#
130+# This file is part of django-testscenarios.
131+#
132+# django-testscenarios is free software: you can redistribute it and/or modify
133+# it under the terms of the GNU Lesser General Public License version 3
134+# as published by the Free Software Foundation
135+#
136+# django-testscenarios is distributed in the hope that it will be useful,
137+# but WITHOUT ANY WARRANTY; without even the implied warranty of
138+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
139+# GNU General Public License for more details.
140+#
141+# You should have received a copy of the GNU Lesser General Public License
142+# along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.
143+
144+"""
145+Helper function for running tests via setup.py test
146+"""
147+
148 import os
149 import sys
150
151 import django
152
153-def run_tests(test_last_n_apps=-1):
154- os.environ['DJANGO_SETTINGS_MODULE'] = 'test_project.settings'
155+
156+def run_tests_for(settings_module_name, test_last_n_apps=-1):
157+ """
158+ Helper function that simplifies testing Django applications via setup.py
159+ test
160+
161+ The idea is to test your application in a small test project. Since not
162+ everything in your project is relevant (you don't want to test
163+ django.contrib.auth gazillion times just because you use it in your
164+ application) run_tests allows you to run just a subset of applications. By
165+ default last item in INSTALLED_APPLICATIONS is tested. You can change it by
166+ calling run_tests() with different argument. If you really want to test all
167+ applications just pass None as test_last_n_apps.
168+ """
169+ os.environ['DJANGO_SETTINGS_MODULE'] = settings_module_name
170+
171 from django.conf import settings
172 from django.test.utils import get_runner
173- test_labels = settings.INSTALLED_APPS[test_last_n_apps:]
174+ if test_last_n_apps is None:
175+ test_labels = None
176+ else:
177+ test_labels = settings.INSTALLED_APPS[test_last_n_apps:]
178 if django.VERSION[0:2] <= (1, 1):
179 # Prior to django 1.2 the runner was a plain function
180 runner_fn = get_runner(settings)
181@@ -18,3 +57,11 @@
182 runner = runner_cls(verbosity=2, interactive=False).run_tests
183 failures = runner(test_labels)
184 sys.exit(failures)
185+
186+
187+def run_tests(test_last_n_apps=-1):
188+ """
189+ Like run_tests_for but assumes that settings_module_name is
190+ "test_project.settings"
191+ """
192+ return run_tests_for("test_project.settings", test_last_n_apps)
193
194=== added file 'django_testscenarios/__init__.py'
195--- django_testscenarios/__init__.py 1970-01-01 00:00:00 +0000
196+++ django_testscenarios/__init__.py 2011-05-23 14:59:46 +0000
197@@ -0,0 +1,17 @@
198+# Copyright (C) 2010, 2011 Linaro Limited
199+#
200+# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
201+#
202+# This file is part of django-testscenarios.
203+#
204+# django-testscenarios is free software: you can redistribute it and/or modify
205+# it under the terms of the GNU Lesser General Public License version 3
206+# as published by the Free Software Foundation
207+#
208+# django-testscenarios is distributed in the hope that it will be useful,
209+# but WITHOUT ANY WARRANTY; without even the implied warranty of
210+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
211+# GNU General Public License for more details.
212+#
213+# You should have received a copy of the GNU Lesser General Public License
214+# along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.
215
216=== modified file 'django_testscenarios/models.py'
217--- django_testscenarios/models.py 2010-11-22 15:06:15 +0000
218+++ django_testscenarios/models.py 2011-05-23 14:59:46 +0000
219@@ -1,4 +1,4 @@
220-# Copyright (C) 2010 Linaro Limited
221+# Copyright (C) 2010, 2011 Linaro Limited
222 #
223 # Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
224 #
225
226=== renamed directory 'test_project' => 'django_testscenarios/test_project'
227=== modified file 'django_testscenarios/test_project/__init__.py'
228--- test_project/__init__.py 2010-11-22 15:06:15 +0000
229+++ django_testscenarios/test_project/__init__.py 2011-05-23 14:59:46 +0000
230@@ -1,4 +1,4 @@
231-# Copyright (C) 2010 Linaro Limited
232+# Copyright (C) 2010, 2011 Linaro Limited
233 #
234 # Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
235 #
236
237=== modified file 'django_testscenarios/test_project/manage.py'
238--- test_project/manage.py 2011-01-03 23:57:16 +0000
239+++ django_testscenarios/test_project/manage.py 2011-05-23 14:59:46 +0000
240@@ -1,5 +1,5 @@
241 #!/usr/bin/env python
242-# Copyright (C) 2010 Linaro Limited
243+# Copyright (C) 2010, 2011 Linaro Limited
244 #
245 # Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
246 #
247@@ -20,7 +20,7 @@
248
249 from django.core.management import execute_manager
250 try:
251- import settings # Assumed to be in the same directory.
252+ import django_testscenarios.test_project.settings as settings
253 except ImportError:
254 import sys
255 sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
256
257=== modified file 'django_testscenarios/test_project/settings.py'
258--- test_project/settings.py 2011-01-04 09:24:44 +0000
259+++ django_testscenarios/test_project/settings.py 2011-05-23 14:59:46 +0000
260@@ -1,4 +1,4 @@
261-# Copyright (C) 2010 Linaro Limited
262+# Copyright (C) 2010, 2011 Linaro Limited
263 #
264 # Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
265 #
266@@ -21,8 +21,4 @@
267
268 locals().update(
269 gen_settings(
270- INSTALLED_APPS=[
271- 'django_testscenarios',
272- ]
273- )
274-)
275+ INSTALLED_APPS=['django_testscenarios']))
276
277=== modified file 'django_testscenarios/test_project/tests.py'
278--- test_project/tests.py 2011-01-03 23:57:16 +0000
279+++ django_testscenarios/test_project/tests.py 2011-05-23 14:59:46 +0000
280@@ -1,4 +1,4 @@
281-# Copyright (C) 2010 Linaro Limited
282+# Copyright (C) 2010, 2011 Linaro Limited
283 #
284 # Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
285 #
286@@ -17,7 +17,11 @@
287 # along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.
288
289
290-from django_testproject.tests import run_tests
291+from django_testproject.tests import run_tests_for
292+
293+
294+def run_tests():
295+ return run_tests_for("django_testscenarios.test_project.settings")
296
297
298 if __name__ == '__main__':
299
300=== modified file 'django_testscenarios/tests.py'
301--- django_testscenarios/tests.py 2010-12-07 21:35:59 +0000
302+++ django_testscenarios/tests.py 2011-05-23 14:59:46 +0000
303@@ -1,4 +1,4 @@
304-# Copyright (C) 2010 Linaro Limited
305+# Copyright (C) 2010, 2011 Linaro Limited
306 #
307 # Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
308 #
309@@ -21,15 +21,13 @@
310 from django.db import models, transaction
311 from django.test import (
312 TestCase as DjangoTestCase,
313- TransactionTestCase as DjangoTransactionTestCase
314-)
315+ TransactionTestCase as DjangoTransactionTestCase)
316
317-from django_testscenarios import (
318+from django_testscenarios.ubertest import (
319 TestCase,
320 TestCaseWithScenarios,
321 TransactionTestCase,
322- TransactionTestCaseWithScenarios,
323-)
324+ TransactionTestCaseWithScenarios)
325
326
327 class TestModel(models.Model):
328@@ -95,8 +93,10 @@
329 finally:
330 transaction.leave_transaction_management()
331
332+
333 # Non-transaction tests
334
335+
336 class TestsWorkWithPlainDjangoTestCase(
337 DjangoTestCase,
338 PlainDatabaseChecks):
339
340=== renamed file 'django_testscenarios/__init__.py' => 'django_testscenarios/ubertest.py'
341--- django_testscenarios/__init__.py 2010-12-07 21:35:59 +0000
342+++ django_testscenarios/ubertest.py 2011-05-23 14:59:46 +0000
343@@ -1,4 +1,4 @@
344-# Copyright (C) 2010 Linaro Limited
345+# Copyright (C) 2010, 2011 Linaro Limited
346 #
347 # Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
348 #
349@@ -16,6 +16,7 @@
350 # You should have received a copy of the GNU Lesser General Public License
351 # along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.
352
353+
354 """
355 An uber-test class for Django that mixes:
356 * testtools.TestCase
357@@ -67,8 +68,7 @@
358 self.__class__.__module__,
359 self.__class__.__name__,
360 self._testMethodName,
361- self._testScenarioName
362- )
363+ self._testScenarioName)
364
365 def shortDescription(self):
366 # XXX this makes setup.py test and test_project/manage.py test
367@@ -176,7 +176,7 @@
368 # cleanup _after_ a transaction test case. This works correctly
369 # since (after sorting test cases) subsequent transaction test case
370 # startup code will purge the database before running user code.
371- #
372+ #
373 # Hence, our implementation makes the TransactionTestCase the base
374 # class and the plain TestCase derived class.
375 django.test.TestCase,
376@@ -190,5 +190,4 @@
377 "TestCase",
378 "TestCaseWithScenarios",
379 "TransactionTestCase",
380- "TransactionTestCaseWithScenarios"
381-]
382+ "TransactionTestCaseWithScenarios"]
383
384=== modified file 'setup.py'
385--- setup.py 2011-02-28 13:52:11 +0000
386+++ setup.py 2011-05-23 14:59:46 +0000
387@@ -20,16 +20,16 @@
388 from setuptools import setup
389
390 setup(
391- name = 'django-testscenarios',
392- version = "0.5.3",
393- author = "Zygmunt Krynicki",
394- author_email = "zygmunt.krynicki@linaro.org",
395- description = "Django-compatible testscenarios.TestWithScenarios",
396- url = 'https://launchpad.net/django-testscenarios',
397- test_suite = 'test_project.tests.run_tests',
398+ name='django-testscenarios',
399+ version="0.6",
400+ author="Zygmunt Krynicki",
401+ author_email="zygmunt.krynicki@linaro.org",
402+ description="Django-compatible testscenarios.TestWithScenarios",
403+ url='https://launchpad.net/django-testscenarios',
404+ test_suite='django_testscenarios.test_project.tests.run_tests',
405 license='LGPLv3',
406- keywords = ['django', 'testing', 'scenarios'],
407- classifiers = [
408+ keywords=['django', 'testing', 'scenarios'],
409+ classifiers=[
410 "Development Status :: 4 - Beta",
411 'Environment :: Web Environment',
412 'Framework :: Django',
413@@ -39,15 +39,12 @@
414 "Programming Language :: Python :: 2.6",
415 "Topic :: Software Development :: Testing",
416 ],
417- zip_safe = True,
418- packages = [
419+ zip_safe=True,
420+ packages=[
421 'django_testproject',
422 'django_testscenarios',
423 ],
424- # dependencies
425 install_requires=[
426 'django >= 1.0',
427 'testtools >= 0.9.2',
428- 'testscenarios >= 0.1',
429- ],
430-)
431+ 'testscenarios >= 0.1'])

Subscribers

People subscribed via source and target branches

to all changes: