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
=== modified file 'django_testproject/settings.py'
--- django_testproject/settings.py 2011-01-04 09:24:44 +0000
+++ django_testproject/settings.py 2011-05-23 14:59:46 +0000
@@ -7,6 +7,9 @@
7import django7import django
88
99
10DJANGO_TESTPROJECT_DIR = os.path.abspath(os.path.dirname(__file__))
11
12
10def _get_default_settings(project_dir):13def _get_default_settings(project_dir):
11 """14 """
12 Produce default settings15 Produce default settings
@@ -28,28 +31,27 @@
28 SITE_ID = 131 SITE_ID = 1
29 TEMPLATE_LOADERS = (32 TEMPLATE_LOADERS = (
30 'django.template.loaders.filesystem.load_template_source',33 'django.template.loaders.filesystem.load_template_source',
31 'django.template.loaders.app_directories.load_template_source',34 'django.template.loaders.app_directories.load_template_source',)
32 )
33 TEMPLATE_DIRS = (35 TEMPLATE_DIRS = (
34 os.path.join(project_dir, "templates")36 os.path.join(project_dir, "templates"),
35 )37 os.path.join(DJANGO_TESTPROJECT_DIR, "templates"))
36 MIDDLEWARE_CLASSES = (38 MIDDLEWARE_CLASSES = (
37 'django.middleware.common.CommonMiddleware',39 'django.middleware.common.CommonMiddleware',
38 'django.contrib.sessions.middleware.SessionMiddleware',40 'django.contrib.sessions.middleware.SessionMiddleware',
39 'django.contrib.auth.middleware.AuthenticationMiddleware',41 'django.contrib.auth.middleware.AuthenticationMiddleware',
40 'django.middleware.transaction.TransactionMiddleware',42 'django.middleware.transaction.TransactionMiddleware',)
41 )
42 if django.VERSION[0:2] >= (1, 2):43 if django.VERSION[0:2] >= (1, 2):
43 DATABASES = {44 DATABASES = {
44 'default': {45 'default': {
45 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.46 # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
46 'NAME': os.path.join(project_dir, 'test.db'), # Or path to database file if using sqlite3.47 'ENGINE': 'django.db.backends.sqlite3',
47 'USER': '', # Not used with sqlite3.48 # Or path to database file if using sqlite3.
48 'PASSWORD': '', # Not used with sqlite3.49 'NAME': os.path.join(project_dir, 'test.db'),
49 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.50 'USER': '', # Not used with sqlite3.
50 'PORT': '', # Set to empty string for default. Not used with sqlite3.51 'PASSWORD': '', # Not used with sqlite3.
51 }52 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
52 }53 'PORT': '', # Set to empty string for default. Not used with sqlite3.
54 }}
53 else:55 else:
54 DATABASE_ENGINE = 'sqlite3'56 DATABASE_ENGINE = 'sqlite3'
55 DATABASE_NAME = os.path.join(project_dir, 'test.db')57 DATABASE_NAME = os.path.join(project_dir, 'test.db')
5658
=== added directory 'django_testproject/templates'
=== added directory 'django_testproject/templates/django_testproject'
=== added file 'django_testproject/templates/django_testproject/base.html'
--- django_testproject/templates/django_testproject/base.html 1970-01-01 00:00:00 +0000
+++ django_testproject/templates/django_testproject/base.html 2011-05-23 14:59:46 +0000
@@ -0,0 +1,10 @@
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE }}" xml:lang="{{ LANGUAGE_CODE }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
5 <title>{% block title %}{% endblock %}</title>
6 </head>
7 <body>
8 {% block content %}{% endblock %}
9 </body>
10</html>
011
=== added directory 'django_testproject/templates/registration'
=== added file 'django_testproject/templates/registration/base.html'
--- django_testproject/templates/registration/base.html 1970-01-01 00:00:00 +0000
+++ django_testproject/templates/registration/base.html 2011-05-23 14:59:46 +0000
@@ -0,0 +1,4 @@
1{% extends "django_testproject/base.html" %}
2
3
4{% block title %}Account management{% endblock %}
05
=== added file 'django_testproject/templates/registration/logged_out.html'
--- django_testproject/templates/registration/logged_out.html 1970-01-01 00:00:00 +0000
+++ django_testproject/templates/registration/logged_out.html 2011-05-23 14:59:46 +0000
@@ -0,0 +1,3 @@
1{% block content %}
2<p>You have been signed out</p>
3{% endblock %}
04
=== added file 'django_testproject/templates/registration/login.html'
--- django_testproject/templates/registration/login.html 1970-01-01 00:00:00 +0000
+++ django_testproject/templates/registration/login.html 2011-05-23 14:59:46 +0000
@@ -0,0 +1,25 @@
1{% extends "registration/base.html" %}
2
3
4{% block title %}{{block.super }} | Sign in {% endblock %}
5
6
7{% block header %}
8{% if next %}
9 <h1>You need to sign-in to access that page</h1>
10{% else %}
11 <h1>Sign in</h1>
12{% endif %}
13{% endblock %}
14
15
16{% block content %}
17<form method="post" action="{% url django.contrib.auth.views.login %}">
18 {% csrf_token %}
19 <p>{{ form.username }}</p>
20 <p>{{ form.password }}</p>
21 {{ form.errors }}
22 <input id="id_submit" type="submit" value="Sign in with username and password" />
23 <input type="hidden" name="next" value="{{ next }}" />
24</form>
25{% endblock %}
026
=== modified file 'django_testproject/tests.py'
--- django_testproject/tests.py 2011-01-19 11:02:44 +0000
+++ django_testproject/tests.py 2011-05-23 14:59:46 +0000
@@ -1,13 +1,52 @@
1# Copyright (C) 2010, 2011 Linaro Limited
2#
3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
4#
5# This file is part of django-testscenarios.
6#
7# django-testscenarios is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Lesser General Public License version 3
9# as published by the Free Software Foundation
10#
11# django-testscenarios is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public License
17# along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.
18
19"""
20Helper function for running tests via setup.py test
21"""
22
1import os23import os
2import sys24import sys
325
4import django26import django
527
6def run_tests(test_last_n_apps=-1):28
7 os.environ['DJANGO_SETTINGS_MODULE'] = 'test_project.settings'29def run_tests_for(settings_module_name, test_last_n_apps=-1):
30 """
31 Helper function that simplifies testing Django applications via setup.py
32 test
33
34 The idea is to test your application in a small test project. Since not
35 everything in your project is relevant (you don't want to test
36 django.contrib.auth gazillion times just because you use it in your
37 application) run_tests allows you to run just a subset of applications. By
38 default last item in INSTALLED_APPLICATIONS is tested. You can change it by
39 calling run_tests() with different argument. If you really want to test all
40 applications just pass None as test_last_n_apps.
41 """
42 os.environ['DJANGO_SETTINGS_MODULE'] = settings_module_name
43
8 from django.conf import settings44 from django.conf import settings
9 from django.test.utils import get_runner45 from django.test.utils import get_runner
10 test_labels = settings.INSTALLED_APPS[test_last_n_apps:]46 if test_last_n_apps is None:
47 test_labels = None
48 else:
49 test_labels = settings.INSTALLED_APPS[test_last_n_apps:]
11 if django.VERSION[0:2] <= (1, 1):50 if django.VERSION[0:2] <= (1, 1):
12 # Prior to django 1.2 the runner was a plain function51 # Prior to django 1.2 the runner was a plain function
13 runner_fn = get_runner(settings)52 runner_fn = get_runner(settings)
@@ -18,3 +57,11 @@
18 runner = runner_cls(verbosity=2, interactive=False).run_tests57 runner = runner_cls(verbosity=2, interactive=False).run_tests
19 failures = runner(test_labels)58 failures = runner(test_labels)
20 sys.exit(failures)59 sys.exit(failures)
60
61
62def run_tests(test_last_n_apps=-1):
63 """
64 Like run_tests_for but assumes that settings_module_name is
65 "test_project.settings"
66 """
67 return run_tests_for("test_project.settings", test_last_n_apps)
2168
=== added file 'django_testscenarios/__init__.py'
--- django_testscenarios/__init__.py 1970-01-01 00:00:00 +0000
+++ django_testscenarios/__init__.py 2011-05-23 14:59:46 +0000
@@ -0,0 +1,17 @@
1# Copyright (C) 2010, 2011 Linaro Limited
2#
3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
4#
5# This file is part of django-testscenarios.
6#
7# django-testscenarios is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Lesser General Public License version 3
9# as published by the Free Software Foundation
10#
11# django-testscenarios is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public License
17# along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.
018
=== modified file 'django_testscenarios/models.py'
--- django_testscenarios/models.py 2010-11-22 15:06:15 +0000
+++ django_testscenarios/models.py 2011-05-23 14:59:46 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2010 Linaro Limited1# Copyright (C) 2010, 2011 Linaro Limited
2#2#
3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
4#4#
55
=== renamed directory 'test_project' => 'django_testscenarios/test_project'
=== modified file 'django_testscenarios/test_project/__init__.py'
--- test_project/__init__.py 2010-11-22 15:06:15 +0000
+++ django_testscenarios/test_project/__init__.py 2011-05-23 14:59:46 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2010 Linaro Limited1# Copyright (C) 2010, 2011 Linaro Limited
2#2#
3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
4#4#
55
=== modified file 'django_testscenarios/test_project/manage.py'
--- test_project/manage.py 2011-01-03 23:57:16 +0000
+++ django_testscenarios/test_project/manage.py 2011-05-23 14:59:46 +0000
@@ -1,5 +1,5 @@
1#!/usr/bin/env python1#!/usr/bin/env python
2# Copyright (C) 2010 Linaro Limited2# Copyright (C) 2010, 2011 Linaro Limited
3#3#
4# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>4# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
5#5#
@@ -20,7 +20,7 @@
2020
21from django.core.management import execute_manager21from django.core.management import execute_manager
22try:22try:
23 import settings # Assumed to be in the same directory.23 import django_testscenarios.test_project.settings as settings
24except ImportError:24except ImportError:
25 import sys25 import sys
26 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__)26 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__)
2727
=== modified file 'django_testscenarios/test_project/settings.py'
--- test_project/settings.py 2011-01-04 09:24:44 +0000
+++ django_testscenarios/test_project/settings.py 2011-05-23 14:59:46 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2010 Linaro Limited1# Copyright (C) 2010, 2011 Linaro Limited
2#2#
3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
4#4#
@@ -21,8 +21,4 @@
2121
22locals().update(22locals().update(
23 gen_settings(23 gen_settings(
24 INSTALLED_APPS=[24 INSTALLED_APPS=['django_testscenarios']))
25 'django_testscenarios',
26 ]
27 )
28)
2925
=== modified file 'django_testscenarios/test_project/tests.py'
--- test_project/tests.py 2011-01-03 23:57:16 +0000
+++ django_testscenarios/test_project/tests.py 2011-05-23 14:59:46 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2010 Linaro Limited1# Copyright (C) 2010, 2011 Linaro Limited
2#2#
3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
4#4#
@@ -17,7 +17,11 @@
17# along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.17# along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.
1818
1919
20from django_testproject.tests import run_tests20from django_testproject.tests import run_tests_for
21
22
23def run_tests():
24 return run_tests_for("django_testscenarios.test_project.settings")
2125
2226
23if __name__ == '__main__':27if __name__ == '__main__':
2428
=== modified file 'django_testscenarios/tests.py'
--- django_testscenarios/tests.py 2010-12-07 21:35:59 +0000
+++ django_testscenarios/tests.py 2011-05-23 14:59:46 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2010 Linaro Limited1# Copyright (C) 2010, 2011 Linaro Limited
2#2#
3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
4#4#
@@ -21,15 +21,13 @@
21from django.db import models, transaction21from django.db import models, transaction
22from django.test import (22from django.test import (
23 TestCase as DjangoTestCase,23 TestCase as DjangoTestCase,
24 TransactionTestCase as DjangoTransactionTestCase24 TransactionTestCase as DjangoTransactionTestCase)
25)
2625
27from django_testscenarios import (26from django_testscenarios.ubertest import (
28 TestCase,27 TestCase,
29 TestCaseWithScenarios,28 TestCaseWithScenarios,
30 TransactionTestCase,29 TransactionTestCase,
31 TransactionTestCaseWithScenarios,30 TransactionTestCaseWithScenarios)
32)
3331
3432
35class TestModel(models.Model):33class TestModel(models.Model):
@@ -95,8 +93,10 @@
95 finally:93 finally:
96 transaction.leave_transaction_management()94 transaction.leave_transaction_management()
9795
96
98# Non-transaction tests97# Non-transaction tests
9998
99
100class TestsWorkWithPlainDjangoTestCase(100class TestsWorkWithPlainDjangoTestCase(
101 DjangoTestCase,101 DjangoTestCase,
102 PlainDatabaseChecks):102 PlainDatabaseChecks):
103103
=== renamed file 'django_testscenarios/__init__.py' => 'django_testscenarios/ubertest.py'
--- django_testscenarios/__init__.py 2010-12-07 21:35:59 +0000
+++ django_testscenarios/ubertest.py 2011-05-23 14:59:46 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2010 Linaro Limited1# Copyright (C) 2010, 2011 Linaro Limited
2#2#
3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>3# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
4#4#
@@ -16,6 +16,7 @@
16# You should have received a copy of the GNU Lesser General Public License16# You should have received a copy of the GNU Lesser General Public License
17# along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.17# along with django-testscenarios. If not, see <http://www.gnu.org/licenses/>.
1818
19
19"""20"""
20An uber-test class for Django that mixes:21An uber-test class for Django that mixes:
21 * testtools.TestCase22 * testtools.TestCase
@@ -67,8 +68,7 @@
67 self.__class__.__module__,68 self.__class__.__module__,
68 self.__class__.__name__,69 self.__class__.__name__,
69 self._testMethodName,70 self._testMethodName,
70 self._testScenarioName71 self._testScenarioName)
71 )
7272
73 def shortDescription(self):73 def shortDescription(self):
74 # XXX this makes setup.py test and test_project/manage.py test74 # XXX this makes setup.py test and test_project/manage.py test
@@ -176,7 +176,7 @@
176 # cleanup _after_ a transaction test case. This works correctly176 # cleanup _after_ a transaction test case. This works correctly
177 # since (after sorting test cases) subsequent transaction test case177 # since (after sorting test cases) subsequent transaction test case
178 # startup code will purge the database before running user code.178 # startup code will purge the database before running user code.
179 # 179 #
180 # Hence, our implementation makes the TransactionTestCase the base180 # Hence, our implementation makes the TransactionTestCase the base
181 # class and the plain TestCase derived class.181 # class and the plain TestCase derived class.
182 django.test.TestCase,182 django.test.TestCase,
@@ -190,5 +190,4 @@
190 "TestCase",190 "TestCase",
191 "TestCaseWithScenarios",191 "TestCaseWithScenarios",
192 "TransactionTestCase",192 "TransactionTestCase",
193 "TransactionTestCaseWithScenarios"193 "TransactionTestCaseWithScenarios"]
194]
195194
=== modified file 'setup.py'
--- setup.py 2011-02-28 13:52:11 +0000
+++ setup.py 2011-05-23 14:59:46 +0000
@@ -20,16 +20,16 @@
20from setuptools import setup20from setuptools import setup
2121
22setup(22setup(
23 name = 'django-testscenarios',23 name='django-testscenarios',
24 version = "0.5.3",24 version="0.6",
25 author = "Zygmunt Krynicki",25 author="Zygmunt Krynicki",
26 author_email = "zygmunt.krynicki@linaro.org",26 author_email="zygmunt.krynicki@linaro.org",
27 description = "Django-compatible testscenarios.TestWithScenarios",27 description="Django-compatible testscenarios.TestWithScenarios",
28 url = 'https://launchpad.net/django-testscenarios',28 url='https://launchpad.net/django-testscenarios',
29 test_suite = 'test_project.tests.run_tests',29 test_suite='django_testscenarios.test_project.tests.run_tests',
30 license='LGPLv3',30 license='LGPLv3',
31 keywords = ['django', 'testing', 'scenarios'],31 keywords=['django', 'testing', 'scenarios'],
32 classifiers = [32 classifiers=[
33 "Development Status :: 4 - Beta",33 "Development Status :: 4 - Beta",
34 'Environment :: Web Environment',34 'Environment :: Web Environment',
35 'Framework :: Django',35 'Framework :: Django',
@@ -39,15 +39,12 @@
39 "Programming Language :: Python :: 2.6",39 "Programming Language :: Python :: 2.6",
40 "Topic :: Software Development :: Testing",40 "Topic :: Software Development :: Testing",
41 ],41 ],
42 zip_safe = True,42 zip_safe=True,
43 packages = [43 packages=[
44 'django_testproject',44 'django_testproject',
45 'django_testscenarios',45 'django_testscenarios',
46 ],46 ],
47 # dependencies
48 install_requires=[47 install_requires=[
49 'django >= 1.0',48 'django >= 1.0',
50 'testtools >= 0.9.2',49 'testtools >= 0.9.2',
51 'testscenarios >= 0.1',50 'testscenarios >= 0.1'])
52 ],
53)

Subscribers

People subscribed via source and target branches

to all changes: