Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
5241763c
Kaydet (Commit)
5241763c
authored
Ara 23, 2013
tarafından
Aymeric Augustin
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Added modify_settings to alter settings containing lists of values.
üst
5891990b
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
229 additions
and
49 deletions
+229
-49
__init__.py
django/test/__init__.py
+2
-2
testcases.py
django/test/testcases.py
+20
-7
utils.py
django/test/utils.py
+63
-12
overview.txt
docs/topics/testing/overview.txt
+86
-24
tests.py
tests/settings_tests/tests.py
+57
-4
test_i18n.py
tests/view_tests/tests/test_i18n.py
+1
-0
No files found.
django/test/__init__.py
Dosyayı görüntüle @
5241763c
...
...
@@ -8,10 +8,10 @@ from django.test.testcases import (
SimpleTestCase
,
LiveServerTestCase
,
skipIfDBFeature
,
skipUnlessDBFeature
)
from
django.test.utils
import
override_settings
from
django.test.utils
import
modify_settings
,
override_settings
__all__
=
[
'Client'
,
'RequestFactory'
,
'TestCase'
,
'TransactionTestCase'
,
'SimpleTestCase'
,
'LiveServerTestCase'
,
'skipIfDBFeature'
,
'skipUnlessDBFeature'
,
'override_settings'
,
'skipUnlessDBFeature'
,
'
modify_settings'
,
'
override_settings'
,
]
django/test/testcases.py
Dosyayı görüntüle @
5241763c
...
...
@@ -32,7 +32,7 @@ from django.test.client import Client
from
django.test.html
import
HTMLParseError
,
parse_html
from
django.test.signals
import
setting_changed
,
template_rendered
from
django.test.utils
import
(
CaptureQueriesContext
,
ContextList
,
override_settings
,
compare_xml
)
override_settings
,
modify_settings
,
compare_xml
)
from
django.utils.encoding
import
force_text
from
django.utils
import
six
from
django.utils.six.moves.urllib.parse
import
urlsplit
,
urlunsplit
,
urlparse
,
unquote
...
...
@@ -164,7 +164,8 @@ class SimpleTestCase(unittest.TestCase):
# The class we'll use for the test client self.client.
# Can be overridden in derived classes.
client_class
=
Client
_custom_settings
=
None
_overridden_settings
=
None
_modified_settings
=
None
def
__call__
(
self
,
result
=
None
):
"""
...
...
@@ -197,9 +198,12 @@ class SimpleTestCase(unittest.TestCase):
* If the class has a 'urls' attribute, replace ROOT_URLCONF with it.
* Clearing the mail test outbox.
"""
if
self
.
_custom_settings
:
self
.
_overridden
=
override_settings
(
**
self
.
_custom_settings
)
self
.
_overridden
.
enable
()
if
self
.
_overridden_settings
:
self
.
_overridden_context
=
override_settings
(
**
self
.
_overridden_settings
)
self
.
_overridden_context
.
enable
()
if
self
.
_modified_settings
:
self
.
_modified_context
=
modify_settings
(
self
.
_modified_settings
)
self
.
_modified_context
.
enable
()
self
.
client
=
self
.
client_class
()
self
.
_urlconf_setup
()
mail
.
outbox
=
[]
...
...
@@ -217,8 +221,10 @@ class SimpleTestCase(unittest.TestCase):
* Putting back the original ROOT_URLCONF if it was changed.
"""
self
.
_urlconf_teardown
()
if
self
.
_custom_settings
:
self
.
_overridden
.
disable
()
if
self
.
_modified_settings
:
self
.
_modified_context
.
disable
()
if
self
.
_overridden_settings
:
self
.
_overridden_context
.
disable
()
def
_urlconf_teardown
(
self
):
set_urlconf
(
None
)
...
...
@@ -233,6 +239,13 @@ class SimpleTestCase(unittest.TestCase):
"""
return
override_settings
(
**
kwargs
)
def
modify_settings
(
self
,
**
kwargs
):
"""
A context manager that temporarily applies changes a list setting and
reverts back to the original value when exiting the context.
"""
return
modify_settings
(
**
kwargs
)
def
assertRedirects
(
self
,
response
,
expected_url
,
status_code
=
302
,
target_status_code
=
200
,
host
=
None
,
msg_prefix
=
''
,
fetch_redirect_response
=
True
):
...
...
django/test/utils.py
Dosyayı görüntüle @
5241763c
...
...
@@ -24,8 +24,10 @@ from django.utils.translation import deactivate
__all__
=
(
'Approximate'
,
'ContextList'
,
'get_runner'
,
'override_settings'
,
'requires_tz_support'
,
'setup_test_environment'
,
'teardown_test_environment'
,
'Approximate'
,
'ContextList'
,
'get_runner'
,
'modify_settings'
,
'override_settings'
,
'requires_tz_support'
,
'setup_test_environment'
,
'teardown_test_environment'
,
)
RESTORE_LOADERS_ATTR
=
'_original_template_source_loaders'
...
...
@@ -191,8 +193,6 @@ class override_settings(object):
"""
def
__init__
(
self
,
**
kwargs
):
self
.
options
=
kwargs
# Special case that requires updating the app cache, a core feature.
self
.
installed_apps
=
self
.
options
.
get
(
'INSTALLED_APPS'
)
def
__enter__
(
self
):
self
.
enable
()
...
...
@@ -207,11 +207,7 @@ class override_settings(object):
raise
Exception
(
"Only subclasses of Django SimpleTestCase can be decorated "
"with override_settings"
)
if
test_func
.
_custom_settings
:
test_func
.
_custom_settings
=
dict
(
test_func
.
_custom_settings
,
**
self
.
options
)
else
:
test_func
.
_custom_settings
=
self
.
options
self
.
save_options
(
test_func
)
return
test_func
else
:
@wraps
(
test_func
)
...
...
@@ -220,14 +216,22 @@ class override_settings(object):
return
test_func
(
*
args
,
**
kwargs
)
return
inner
def
save_options
(
self
,
test_func
):
if
test_func
.
_overridden_settings
is
None
:
test_func
.
_overridden_settings
=
self
.
options
else
:
# Duplicate dict to prevent subclasses from altering their parent.
test_func
.
_overridden_settings
=
dict
(
test_func
.
_overridden_settings
,
**
self
.
options
)
def
enable
(
self
):
override
=
UserSettingsHolder
(
settings
.
_wrapped
)
for
key
,
new_value
in
self
.
options
.
items
():
setattr
(
override
,
key
,
new_value
)
self
.
wrapped
=
settings
.
_wrapped
settings
.
_wrapped
=
override
if
self
.
installed_apps
is
not
None
:
app_cache
.
set_installed_apps
(
se
lf
.
installed_apps
)
if
'INSTALLED_APPS'
in
self
.
options
:
app_cache
.
set_installed_apps
(
se
ttings
.
INSTALLED_APPS
)
for
key
,
new_value
in
self
.
options
.
items
():
setting_changed
.
send
(
sender
=
settings
.
_wrapped
.
__class__
,
setting
=
key
,
value
=
new_value
,
enter
=
True
)
...
...
@@ -235,7 +239,7 @@ class override_settings(object):
def
disable
(
self
):
settings
.
_wrapped
=
self
.
wrapped
del
self
.
wrapped
if
self
.
installed_apps
is
not
None
:
if
'INSTALLED_APPS'
in
self
.
options
:
app_cache
.
unset_installed_apps
()
for
key
in
self
.
options
:
new_value
=
getattr
(
settings
,
key
,
None
)
...
...
@@ -243,6 +247,53 @@ class override_settings(object):
setting
=
key
,
value
=
new_value
,
enter
=
False
)
class
modify_settings
(
override_settings
):
"""
Like override_settings, but makes it possible to append, prepend or remove
items instead of redefining the entire list.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
if
args
:
# Hack used when instaciating from SimpleTestCase._pre_setup.
assert
not
kwargs
self
.
operations
=
args
[
0
]
else
:
assert
not
args
self
.
operations
=
list
(
kwargs
.
items
())
def
save_options
(
self
,
test_func
):
if
test_func
.
_modified_settings
is
None
:
test_func
.
_modified_settings
=
self
.
operations
else
:
# Duplicate list to prevent subclasses from altering their parent.
test_func
.
_modified_settings
=
list
(
test_func
.
_modified_settings
)
+
self
.
operations
def
enable
(
self
):
self
.
options
=
{}
for
name
,
operations
in
self
.
operations
:
try
:
# When called from SimpleTestCase._pre_setup, values may be
# overridden several times; cumulate changes.
value
=
self
.
options
[
name
]
except
KeyError
:
value
=
list
(
getattr
(
settings
,
name
,
[]))
for
action
,
items
in
operations
.
items
():
# items my be a single value or an iterable.
if
isinstance
(
items
,
six
.
string_types
):
items
=
[
items
]
if
action
==
'append'
:
value
=
value
+
[
item
for
item
in
items
if
item
not
in
value
]
elif
action
==
'prepend'
:
value
=
[
item
for
item
in
items
if
item
not
in
value
]
+
value
elif
action
==
'remove'
:
value
=
[
item
for
item
in
value
if
item
not
in
items
]
else
:
raise
ValueError
(
"Unsupported action:
%
s"
%
action
)
self
.
options
[
name
]
=
value
super
(
modify_settings
,
self
)
.
enable
()
def
compare_xml
(
want
,
got
):
"""Tries to do a 'xml-comparison' of want and got. Plain string
comparison doesn't always work because, for example, attribute
...
...
docs/topics/testing/overview.txt
Dosyayı görüntüle @
5241763c
...
...
@@ -1335,7 +1335,7 @@ Overriding settings
For testing purposes it's often useful to change a setting temporarily and
revert to the original value after running the testing code. For this use case
Django provides a standard Python context manager (see :pep:`343`)
Django provides a standard Python context manager (see :pep:`343`)
called
:meth:`~django.test.SimpleTestCase.settings`, which can be used like this::
from django.test import TestCase
...
...
@@ -1356,12 +1356,41 @@ Django provides a standard Python context manager (see :pep:`343`)
This example will override the :setting:`LOGIN_URL` setting for the code
in the ``with`` block and reset its value to the previous state afterwards.
.. method:: SimpleTestCase.modify_settings
.. versionadded:: 1.7
It can prove unwieldy to redefine settings that contain a list of values. In
practice, adding or removing values is often sufficient. The
:meth:`~django.test.SimpleTestCase.modify_settings` context manager makes it
easy::
from django.test import TestCase
class MiddlewareTestCase(TestCase):
def test_cache_middleware(self):
with self.modify_settings(MIDDLEWARE_CLASSES={
'append': 'django.middleware.cache.FetchFromCacheMiddleware',
'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
'remove': [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
],
}):
response = self.client.get('/')
# ...
For each action, you can supply either a list of values or a string. When the
value already exists in the list, ``append`` and ``prepend`` have no effect;
neither does ``remove`` when the value doesn't exist.
.. function:: override_settings
In case you want to override a setting for just one test method or even the
whole :class:`~django.test.TestCase` class, Django provides the
:func:`~django.test.override_settings` decorator (see :pep:`318`). It's
used like this::
In case you want to override a setting for a test method, Django provides the
:func:`~django.test.override_settings` decorator (see :pep:`318`). It's used
like this::
from django.test import TestCase, override_settings
...
...
@@ -1372,7 +1401,7 @@ used like this::
response = self.client.get('/sekrit/')
self.assertRedirects(response, '/other/login/?next=/sekrit/')
The decorator can also be applied to
test case
classes::
The decorator can also be applied to
:class:`~django.test.TestCase`
classes::
from django.test import TestCase, override_settings
...
...
@@ -1385,17 +1414,50 @@ The decorator can also be applied to test case classes::
.. versionchanged:: 1.7
Previously, ``override_settings`` was imported from
``django.test.utils``.
Previously, ``override_settings`` was imported from ``django.test.utils``.
.. function:: modify_settings
.. versionadded:: 1.7
Likewise, Django provides the :func:`~django.test.modify_settings`
decorator::
from django.test import TestCase, modify_settings
class MiddlewareTestCase(TestCase):
@modify_settings(MIDDLEWARE_CLASSES={
'append': 'django.middleware.cache.FetchFromCacheMiddleware',
'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
})
def test_cache_middleware(self):
response = self.client.get('/')
# ...
The decorator can also be applied to test case classes::
from django.test import TestCase, modify_settings
@modify_settings(MIDDLEWARE_CLASSES={
'append': 'django.middleware.cache.FetchFromCacheMiddleware',
'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
})
class MiddlewareTestCase(TestCase):
def test_cache_middleware(self):
response = self.client.get('/')
# ...
.. note::
When given a class, the decorator modifies the class directly and
returns it; it doesn't create and return a modified copy of it. So if
you try to tweak the above example to assign the return value to a
different name than ``LoginTestCase``, you may be surprised to find that
the original ``LoginTestCase`` is still equally affected by the
decorator.
When given a class, these decorators modify the class directly and return
it; they don't create and return a modified copy of it. So if you try to
tweak the above examples to assign the return value to a different name
than ``LoginTestCase`` or ``MiddlewareTestCase``, you may be surprised to
find that the original test case classes are still equally affected by the
decorator. For a given class, :func:`~django.test.modify_settings` is
always applied after :func:`~django.test.override_settings`.
.. warning::
...
...
@@ -1403,17 +1465,17 @@ The decorator can also be applied to test case classes::
initialization of Django internals. If you change them with
``override_settings``, the setting is changed if you access it via the
``django.conf.settings`` module, however, Django's internals access it
differently. Effectively, using ``override_settings`` with these settings
is probably not going to do what you expect it to do.
differently. Effectively, using :func:`~django.test.override_settings` or
:func:`~django.test.modify_settings` with these settings is probably not
going to do what you expect it to do.
We do not recommend
using ``override_settings`` with :setting:`DATABASES`.
Using ``override_settings`` with :setting:`CACHES` is possible, but a bit
tricky if you are
using internals that make using of caching, like
We do not recommend
altering the :setting:`DATABASES` setting. Altering
the :setting:`CACHES` setting is possible, but a bit tricky if you are
using internals that make using of caching, like
:mod:`django.contrib.sessions`. For example, you will have to reinitialize
the session backend in a test that uses cached sessions and overrides
:setting:`CACHES`.
You can also simulate the absence of a setting by deleting it after settings
have been overridden, like this::
...
...
@@ -1423,10 +1485,10 @@ have been overridden, like this::
...
When overriding settings, make sure to handle the cases in which your app's
code uses a cache or similar feature that retains state even if the
setting is changed. Django provides the
:data:`django.test.signals.setting_changed` signal that lets you register
callbacks to clean up and otherwise reset state
when settings are changed.
code uses a cache or similar feature that retains state even if the
setting is
changed. Django provides the :data:`django.test.signals.setting_changed`
signal that lets you register callbacks to clean up and otherwise reset state
when settings are changed.
Django itself uses this signal to reset various data:
...
...
tests/settings_tests/tests.py
Dosyayı görüntüle @
5241763c
...
...
@@ -6,19 +6,57 @@ from django.conf import settings
from
django.core.exceptions
import
ImproperlyConfigured
from
django.http
import
HttpRequest
from
django.test
import
SimpleTestCase
,
TransactionTestCase
,
TestCase
,
signals
from
django.test.utils
import
override_settings
from
django.test.utils
import
modify_settings
,
override_settings
from
django.utils
import
six
@override_settings
(
TEST
=
'override'
,
TEST_OUTER
=
'outer'
)
@modify_settings
(
ITEMS
=
{
'prepend'
:
[
'b'
],
'append'
:
[
'd'
],
'remove'
:
[
'a'
,
'e'
]
})
@override_settings
(
ITEMS
=
[
'a'
,
'c'
,
'e'
],
ITEMS_OUTER
=
[
1
,
2
,
3
],
TEST
=
'override'
,
TEST_OUTER
=
'outer'
)
class
FullyDecoratedTranTestCase
(
TransactionTestCase
):
available_apps
=
[]
def
test_override
(
self
):
self
.
assertListEqual
(
settings
.
ITEMS
,
[
'b'
,
'c'
,
'd'
])
self
.
assertListEqual
(
settings
.
ITEMS_OUTER
,
[
1
,
2
,
3
])
self
.
assertEqual
(
settings
.
TEST
,
'override'
)
self
.
assertEqual
(
settings
.
TEST_OUTER
,
'outer'
)
@modify_settings
(
ITEMS
=
{
'append'
:
[
'e'
,
'f'
],
'prepend'
:
[
'a'
],
'remove'
:
[
'd'
,
'c'
],
})
def
test_method_list_override
(
self
):
self
.
assertListEqual
(
settings
.
ITEMS
,
[
'a'
,
'b'
,
'e'
,
'f'
])
self
.
assertListEqual
(
settings
.
ITEMS_OUTER
,
[
1
,
2
,
3
])
@modify_settings
(
ITEMS
=
{
'append'
:
[
'b'
],
'prepend'
:
[
'd'
],
'remove'
:
[
'a'
,
'c'
,
'e'
],
})
def
test_method_list_override_no_ops
(
self
):
self
.
assertListEqual
(
settings
.
ITEMS
,
[
'b'
,
'd'
])
@modify_settings
(
ITEMS
=
{
'append'
:
'e'
,
'prepend'
:
'a'
,
'remove'
:
'c'
,
})
def
test_method_list_override_strings
(
self
):
self
.
assertListEqual
(
settings
.
ITEMS
,
[
'a'
,
'b'
,
'd'
,
'e'
])
@modify_settings
(
ITEMS
=
{
'remove'
:
[
'b'
,
'd'
]})
@modify_settings
(
ITEMS
=
{
'append'
:
[
'b'
],
'prepend'
:
[
'd'
]})
def
test_method_list_override_nested_order
(
self
):
self
.
assertListEqual
(
settings
.
ITEMS
,
[
'd'
,
'c'
,
'b'
])
@override_settings
(
TEST
=
'override2'
)
def
test_method_override
(
self
):
self
.
assertEqual
(
settings
.
TEST
,
'override2'
)
...
...
@@ -31,14 +69,26 @@ class FullyDecoratedTranTestCase(TransactionTestCase):
self
.
assertEqual
(
FullyDecoratedTranTestCase
.
__module__
,
__name__
)
@override_settings
(
TEST
=
'override'
)
@modify_settings
(
ITEMS
=
{
'prepend'
:
[
'b'
],
'append'
:
[
'd'
],
'remove'
:
[
'a'
,
'e'
]
})
@override_settings
(
ITEMS
=
[
'a'
,
'c'
,
'e'
],
TEST
=
'override'
)
class
FullyDecoratedTestCase
(
TestCase
):
def
test_override
(
self
):
self
.
assertListEqual
(
settings
.
ITEMS
,
[
'b'
,
'c'
,
'd'
])
self
.
assertEqual
(
settings
.
TEST
,
'override'
)
@modify_settings
(
ITEMS
=
{
'append'
:
'e'
,
'prepend'
:
'a'
,
'remove'
:
'c'
,
})
@override_settings
(
TEST
=
'override2'
)
def
test_method_override
(
self
):
self
.
assertListEqual
(
settings
.
ITEMS
,
[
'a'
,
'b'
,
'd'
,
'e'
])
self
.
assertEqual
(
settings
.
TEST
,
'override2'
)
...
...
@@ -73,14 +123,17 @@ class ClassDecoratedTestCase(ClassDecoratedTestCaseSuper):
self
.
fail
()
@override_settings
(
TEST
=
'override-parent'
)
@modify_settings
(
ITEMS
=
{
'append'
:
'mother'
})
@override_settings
(
ITEMS
=
[
'father'
],
TEST
=
'override-parent'
)
class
ParentDecoratedTestCase
(
TestCase
):
pass
@modify_settings
(
ITEMS
=
{
'append'
:
[
'child'
]})
@override_settings
(
TEST
=
'override-child'
)
class
ChildDecoratedTestCase
(
ParentDecoratedTestCase
):
def
test_override_settings_inheritance
(
self
):
self
.
assertEqual
(
settings
.
ITEMS
,
[
'father'
,
'mother'
,
'child'
])
self
.
assertEqual
(
settings
.
TEST
,
'override-child'
)
...
...
tests/view_tests/tests/test_i18n.py
Dosyayı görüntüle @
5241763c
...
...
@@ -135,6 +135,7 @@ class JsI18NTests(TestCase):
response
=
self
.
client
.
get
(
'/views/jsi18n_admin/?language=de'
)
self
.
assertContains
(
response
,
'
\\
x04'
)
class
JsI18NTestsMultiPackage
(
TestCase
):
"""
Tests for django views in django/views/i18n.py that need to change
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment