mirror of
https://github.com/django/django.git
synced 2025-07-05 10:19:20 +00:00
[gsoc2009-testing] Creating initial docs files. Windmill multi-module naming workaround implemented in regression suite. Added tests for admin_widgets. Implemented a tests to ensure fresh session state at end of windmill test.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/test-improvements@11129 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
a8817035af
commit
8639d7e2d3
@ -5,25 +5,26 @@ import sys, os
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
import types
|
import types
|
||||||
import logging
|
import logging
|
||||||
|
import threading
|
||||||
|
|
||||||
class ServerContainer(object):
|
class ServerContainer(object):
|
||||||
start_test_server = djangotest.start_test_server
|
start_test_server = djangotest.start_test_server
|
||||||
stop_test_server = djangotest.stop_test_server
|
stop_test_server = djangotest.stop_test_server
|
||||||
|
|
||||||
def attempt_import(name, suffix):
|
def attempt_import(name, suffix):
|
||||||
try:
|
try:
|
||||||
mod = __import__(name+'.'+suffix)
|
mod = __import__(name+'.'+suffix)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
mod = None
|
mod = None
|
||||||
if mod is not None:
|
if mod is not None:
|
||||||
s = name.split('.')
|
s = name.split('.')
|
||||||
mod = __import__(s.pop(0))
|
mod = __import__(s.pop(0))
|
||||||
for x in s+[suffix]:
|
for x in s+[suffix]:
|
||||||
try:
|
try:
|
||||||
mod = getattr(mod, x)
|
mod = getattr(mod, x)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
pass
|
pass
|
||||||
return mod
|
return mod
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
|
|
||||||
@ -54,14 +55,6 @@ class Command(BaseCommand):
|
|||||||
sys.argv.remove('manage.py')
|
sys.argv.remove('manage.py')
|
||||||
if 'test_windmill' in sys.argv:
|
if 'test_windmill' in sys.argv:
|
||||||
sys.argv.remove('test_windmill')
|
sys.argv.remove('test_windmill')
|
||||||
server_container = ServerContainer()
|
|
||||||
server_container.start_test_server()
|
|
||||||
|
|
||||||
global_settings.TEST_URL = 'http://localhost:%d' % server_container.server_thread.port
|
|
||||||
|
|
||||||
# import windmill
|
|
||||||
# windmill.stdout, windmill.stdin = sys.stdout, sys.stdin
|
|
||||||
from windmill.authoring import setup_module, teardown_module
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
tests = []
|
tests = []
|
||||||
@ -69,7 +62,7 @@ class Command(BaseCommand):
|
|||||||
for suffix in ['tests', 'wmtests', 'windmilltests']:
|
for suffix in ['tests', 'wmtests', 'windmilltests']:
|
||||||
x = attempt_import(name, suffix)
|
x = attempt_import(name, suffix)
|
||||||
if x is not None: tests.append((suffix,x,));
|
if x is not None: tests.append((suffix,x,));
|
||||||
|
wmfixs = []
|
||||||
wmtests = []
|
wmtests = []
|
||||||
for (ttype, mod,) in tests:
|
for (ttype, mod,) in tests:
|
||||||
if ttype == 'tests':
|
if ttype == 'tests':
|
||||||
@ -85,6 +78,28 @@ class Command(BaseCommand):
|
|||||||
wmtests.append(os.path.join(*os.path.split(os.path.abspath(mod.__file__))[:-1]))
|
wmtests.append(os.path.join(*os.path.split(os.path.abspath(mod.__file__))[:-1]))
|
||||||
else:
|
else:
|
||||||
wmtests.append(os.path.abspath(mod.__file__))
|
wmtests.append(os.path.abspath(mod.__file__))
|
||||||
|
# Look for any attribute named fixtures and try to load it.
|
||||||
|
if hasattr(mod, 'fixtures'):
|
||||||
|
for fixture in getattr(mod, 'fixtures'):
|
||||||
|
wmfixs.append(fixture)
|
||||||
|
|
||||||
|
# Create the threaded server.
|
||||||
|
server_container = ServerContainer()
|
||||||
|
# Set the server's 'fixtures' attribute so they can be loaded in-thread if using sqlite's memory backend.
|
||||||
|
server_container.__setattr__('fixtures', wmfixs)
|
||||||
|
# Start the server thread.
|
||||||
|
started = server_container.start_test_server()
|
||||||
|
|
||||||
|
print 'Waiting for threaded server to come online.'
|
||||||
|
started.wait()
|
||||||
|
print 'DB Ready, Server online.'
|
||||||
|
|
||||||
|
global_settings.TEST_URL = 'http://localhost:%d' % server_container.server_thread.port
|
||||||
|
|
||||||
|
# import windmill
|
||||||
|
# windmill.stdout, windmill.stdin = sys.stdout, sys.stdin
|
||||||
|
from windmill.authoring import setup_module, teardown_module
|
||||||
|
|
||||||
|
|
||||||
if len(wmtests) is 0:
|
if len(wmtests) is 0:
|
||||||
print 'Sorry, no windmill tests found.'
|
print 'Sorry, no windmill tests found.'
|
||||||
|
@ -25,6 +25,7 @@ you quickly accomplish common tasks.
|
|||||||
outputting-csv
|
outputting-csv
|
||||||
outputting-pdf
|
outputting-pdf
|
||||||
static-files
|
static-files
|
||||||
|
windmill-tests
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
|
92
docs/howto/windmill-tests.txt
Normal file
92
docs/howto/windmill-tests.txt
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
.. _howto-windmill-tests:
|
||||||
|
|
||||||
|
Writing a Functional Tests with Windmill
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
.. currentmodule:: django.test
|
||||||
|
|
||||||
|
If you need to provide custom file storage -- a common example is storing files
|
||||||
|
on some remote system -- you can do so by defining a custom storage class.
|
||||||
|
You'll need to follow these steps:
|
||||||
|
|
||||||
|
#. Your custom storage system must be a subclass of
|
||||||
|
``django.core.files.storage.Storage``::
|
||||||
|
|
||||||
|
from django.core.files.storage import Storage
|
||||||
|
|
||||||
|
class MyStorage(Storage):
|
||||||
|
...
|
||||||
|
|
||||||
|
#. Django must be able to instantiate your storage system without any arguments.
|
||||||
|
This means that any settings should be taken from ``django.conf.settings``::
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.files.storage import Storage
|
||||||
|
|
||||||
|
class MyStorage(Storage):
|
||||||
|
def __init__(self, option=None):
|
||||||
|
if not option:
|
||||||
|
option = settings.CUSTOM_STORAGE_OPTIONS
|
||||||
|
...
|
||||||
|
|
||||||
|
#. Your storage class must implement the ``_open()`` and ``_save()`` methods,
|
||||||
|
along with any other methods appropriate to your storage class. See below for
|
||||||
|
more on these methods.
|
||||||
|
|
||||||
|
In addition, if your class provides local file storage, it must override
|
||||||
|
the ``path()`` method.
|
||||||
|
|
||||||
|
Your custom storage system may override any of the storage methods explained in
|
||||||
|
:ref:`ref-files-storage`, but you **must** implement the following methods:
|
||||||
|
|
||||||
|
* :meth:`Storage.delete`
|
||||||
|
* :meth:`Storage.exists`
|
||||||
|
* :meth:`Storage.listdir`
|
||||||
|
* :meth:`Storage.size`
|
||||||
|
* :meth:`Storage.url`
|
||||||
|
|
||||||
|
You'll also usually want to use hooks specifically designed for custom storage
|
||||||
|
objects. These are:
|
||||||
|
|
||||||
|
``_open(name, mode='rb')``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
**Required**.
|
||||||
|
|
||||||
|
Called by ``Storage.open()``, this is the actual mechanism the storage class
|
||||||
|
uses to open the file. This must return a ``File`` object, though in most cases,
|
||||||
|
you'll want to return some subclass here that implements logic specific to the
|
||||||
|
backend storage system.
|
||||||
|
|
||||||
|
``_save(name, content)``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Called by ``Storage.save()``. The ``name`` will already have gone through
|
||||||
|
``get_valid_name()`` and ``get_available_name()``, and the ``content`` will be a
|
||||||
|
``File`` object itself.
|
||||||
|
|
||||||
|
Should return the actual name of name of the file saved (usually the ``name``
|
||||||
|
passed in, but if the storage needs to change the file name return the new name
|
||||||
|
instead).
|
||||||
|
|
||||||
|
``get_valid_name(name)``
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Returns a filename suitable for use with the underlying storage system. The
|
||||||
|
``name`` argument passed to this method is the original filename sent to the
|
||||||
|
server, after having any path information removed. Override this to customize
|
||||||
|
how non-standard characters are converted to safe filenames.
|
||||||
|
|
||||||
|
The code provided on ``Storage`` retains only alpha-numeric characters, periods
|
||||||
|
and underscores from the original filename, removing everything else.
|
||||||
|
|
||||||
|
``get_available_name(name)``
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Returns a filename that is available in the storage mechanism, possibly taking
|
||||||
|
the provided filename into account. The ``name`` argument passed to this method
|
||||||
|
will have already cleaned to a filename valid for the storage system, according
|
||||||
|
to the ``get_valid_name()`` method described above.
|
||||||
|
|
||||||
|
The code provided on ``Storage`` simply appends underscores to the filename
|
||||||
|
until it finds one that's available in the destination directory.
|
@ -142,7 +142,9 @@ The development process
|
|||||||
:ref:`Overview <ref-django-admin>` |
|
:ref:`Overview <ref-django-admin>` |
|
||||||
:ref:`Adding custom commands <howto-custom-management-commands>`
|
:ref:`Adding custom commands <howto-custom-management-commands>`
|
||||||
|
|
||||||
* **Testing:** :ref:`Overview <topics-testing>`
|
* **Testing:**
|
||||||
|
:ref:`Overview <topics-testing>` |
|
||||||
|
:ref:`Windmill <howto-windmill-tests>`
|
||||||
|
|
||||||
* **Deployment:**
|
* **Deployment:**
|
||||||
:ref:`Overview <howto-deployment-index>` |
|
:ref:`Overview <howto-deployment-index>` |
|
||||||
|
@ -20,4 +20,3 @@ API Reference
|
|||||||
signals
|
signals
|
||||||
templates/index
|
templates/index
|
||||||
unicode
|
unicode
|
||||||
|
|
||||||
|
@ -400,7 +400,7 @@ Some of the things you can do with the test client are:
|
|||||||
a template context that contains certain values.
|
a template context that contains certain values.
|
||||||
|
|
||||||
Note that the test client is not intended to be a replacement for Twill_,
|
Note that the test client is not intended to be a replacement for Twill_,
|
||||||
Selenium_, or other "in-browser" frameworks. Django's test client has
|
Windmill_, or other "in-browser" frameworks. Django's test client has
|
||||||
a different focus. In short:
|
a different focus. In short:
|
||||||
|
|
||||||
* Use Django's test client to establish that the correct view is being
|
* Use Django's test client to establish that the correct view is being
|
||||||
@ -409,10 +409,15 @@ a different focus. In short:
|
|||||||
* Use in-browser frameworks such as Twill and Selenium to test *rendered*
|
* Use in-browser frameworks such as Twill and Selenium to test *rendered*
|
||||||
HTML and the *behavior* of Web pages, namely JavaScript functionality.
|
HTML and the *behavior* of Web pages, namely JavaScript functionality.
|
||||||
|
|
||||||
A comprehensive test suite should use a combination of both test types.
|
A comprehensive test suite should use a combination of both test types. Which
|
||||||
|
is why Django makes it easy to integrate with 3rd party test runners via the
|
||||||
|
:setting:`TEST_RUNNER` setting. For convenience, Django ships a runner for
|
||||||
|
the framework used in testing the :ref:`admin interface, <ref-contrib-admin>`
|
||||||
|
Windmill_. Details on integrating Windmill tests with Django are available
|
||||||
|
:ref:`here. <howto-windmill-test>`
|
||||||
|
|
||||||
.. _Twill: http://twill.idyll.org/
|
.. _Twill: http://twill.idyll.org/
|
||||||
.. _Selenium: http://www.openqa.org/selenium/
|
.. _Windmill: http://www.getwindmill.com/
|
||||||
|
|
||||||
Overview and a quick example
|
Overview and a quick example
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -1420,23 +1420,23 @@ class AdminInlineTests(TestCase):
|
|||||||
self.failUnlessEqual(FancyDoodad.objects.count(), 1)
|
self.failUnlessEqual(FancyDoodad.objects.count(), 1)
|
||||||
self.failUnlessEqual(FancyDoodad.objects.all()[0].name, "Fancy Doodad 1 Updated")
|
self.failUnlessEqual(FancyDoodad.objects.all()[0].name, "Fancy Doodad 1 Updated")
|
||||||
|
|
||||||
import os
|
# import os
|
||||||
#from django.test import windmill_tests as djangotest
|
# from django.test import windmill_tests as djangotest
|
||||||
#from windmill.authoring import djangotest
|
# #from windmill.authoring import djangotest
|
||||||
#from windmill.conf import global_settings
|
# #from windmill.conf import global_settings
|
||||||
|
#
|
||||||
# class TestProjectWindmillTest(djangotest.WindmillDjangoUnitTest):
|
# class TestProjectWindmillTest(djangotest.WindmillDjangoUnitTest):
|
||||||
# fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml', 'admin-views-unicode.xml',
|
# fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml', 'admin-views-unicode.xml',
|
||||||
# 'multiple-child-classes', 'admin-views-actions.xml', 'string-primary-key.xml', 'admin-views-person.xml']
|
# 'multiple-child-classes', 'admin-views-actions.xml', 'string-primary-key.xml', 'admin-views-person.xml']
|
||||||
# test_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'windmilltests')
|
# test_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'windmilltests')
|
||||||
# #test_dir = os.path.dirname(os.path.abspath(__file__))
|
# #test_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
# #test_dir = os.path.dirname(os.path.abspath(__file__))
|
# #test_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
# browser = 'firefox'
|
# browser = 'firefox'
|
||||||
# test_url = 'http://localhost:8000/test_admin/admin/'
|
# test_url = 'http://localhost:8000/test_admin/admin/'
|
||||||
# global_settings.TEST_URL = test_url
|
# #global_settings.TEST_URL = test_url
|
||||||
|
#
|
||||||
# def test_tryout(self):
|
# # def test_tryout(self):
|
||||||
# pass
|
# # pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
fixtures = ['admin-views-users.xml',
|
||||||
|
'admin-views-colors.xml',
|
||||||
|
'admin-views-fabrics.xml',
|
||||||
|
'admin-views-unicode.xml',
|
||||||
|
'multiple-child-classes',
|
||||||
|
'admin-views-actions.xml',
|
||||||
|
'string-primary-key.xml',
|
||||||
|
'admin-views-person.xml']
|
||||||
|
|
||||||
# import os
|
# import os
|
||||||
# from django.test import windmill_tests as djangotest
|
# from django.test import windmill_tests as djangotest
|
||||||
# #from windmill.authoring import djangotest
|
# #from windmill.authoring import djangotest
|
||||||
@ -5,6 +14,7 @@
|
|||||||
from windmill.conf import global_settings
|
from windmill.conf import global_settings
|
||||||
ADMIN_URL = "%s/test_admin/admin" % global_settings.TEST_URL
|
ADMIN_URL = "%s/test_admin/admin" % global_settings.TEST_URL
|
||||||
#ADMIN_URL = 'http://localhost:8000/test_admin/admin/'
|
#ADMIN_URL = 'http://localhost:8000/test_admin/admin/'
|
||||||
|
#['regressiontests/admin_views/fixtures/%s' % fix for fix in ]
|
||||||
|
|
||||||
#
|
#
|
||||||
# class TestProjectWindmillTest(djangotest.WindmillDjangoUnitTest):
|
# class TestProjectWindmillTest(djangotest.WindmillDjangoUnitTest):
|
||||||
@ -21,11 +31,15 @@ ADMIN_URL = "%s/test_admin/admin" % global_settings.TEST_URL
|
|||||||
# # pass
|
# # pass
|
||||||
#
|
#
|
||||||
from windmill.authoring import WindmillTestClient
|
from windmill.authoring import WindmillTestClient
|
||||||
#from django.test.windmill_tests import calling_func_name
|
from django.test.utils import calling_func_name
|
||||||
|
|
||||||
|
# import functest
|
||||||
|
# functest.modules_passed = []
|
||||||
|
# functest.modules_failed = []
|
||||||
|
|
||||||
def test_loginAndSetup():
|
def test_loginAndSetup():
|
||||||
'''Mostly just a proof of concept to test working order of tests.'''
|
'''Mostly just a proof of concept to test working order of tests.'''
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
# print dir(client)
|
# print dir(client)
|
||||||
# print dir(client.open)
|
# print dir(client.open)
|
||||||
@ -83,7 +97,7 @@ def test_loginAndSetup():
|
|||||||
|
|
||||||
def test_changeListNamingLinkingHistory():
|
def test_changeListNamingLinkingHistory():
|
||||||
'''Creating a Model with strings for pk, and checking history.'''
|
'''Creating a Model with strings for pk, and checking history.'''
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
# client.open(url=ADMIN_URL)
|
# client.open(url=ADMIN_URL)
|
||||||
@ -118,7 +132,7 @@ def test_changeListNamingLinkingHistory():
|
|||||||
|
|
||||||
def test_filtersSearchOnChangeList():
|
def test_filtersSearchOnChangeList():
|
||||||
'''Testing Updates and Filters/Search on Person Models'''
|
'''Testing Updates and Filters/Search on Person Models'''
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
@ -165,7 +179,7 @@ def test_filtersSearchOnChangeList():
|
|||||||
|
|
||||||
def test_defaultDeleteAdminAction():
|
def test_defaultDeleteAdminAction():
|
||||||
'''Admin Actions test. Test the default delete action.'''
|
'''Admin Actions test. Test the default delete action.'''
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
@ -180,7 +194,7 @@ def test_defaultDeleteAdminAction():
|
|||||||
client.asserts.assertNode(link=u'Horizontal')
|
client.asserts.assertNode(link=u'Horizontal')
|
||||||
|
|
||||||
def test_dateTimeModelsandWidgets():
|
def test_dateTimeModelsandWidgets():
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
@ -250,7 +264,7 @@ def test_dateTimeModelsandWidgets():
|
|||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
|
||||||
def test_inlineEditandCreate():
|
def test_inlineEditandCreate():
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
@ -276,7 +290,7 @@ def test_inlineEditandCreate():
|
|||||||
|
|
||||||
|
|
||||||
def test_adminActionEmptyModels():
|
def test_adminActionEmptyModels():
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
@ -339,7 +353,7 @@ def test_adminActionEmptyModels():
|
|||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
|
||||||
def test_parentChildRelationship():
|
def test_parentChildRelationship():
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
@ -374,7 +388,7 @@ def test_parentChildRelationship():
|
|||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
|
||||||
def test_AdminAuthContrib():
|
def test_AdminAuthContrib():
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
@ -423,7 +437,7 @@ def test_AdminAuthContrib():
|
|||||||
|
|
||||||
|
|
||||||
def test_contribFlatSitesRedirect():
|
def test_contribFlatSitesRedirect():
|
||||||
client = WindmillTestClient(__name__)
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
client.open(url=ADMIN_URL)
|
client.open(url=ADMIN_URL)
|
||||||
client.waits.forPageLoad(timeout=u'20000')
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
@ -496,3 +510,17 @@ def test_contribFlatSitesRedirect():
|
|||||||
client.asserts.assertText(xpath=u'/html/body', validator=u'\nThis is some unique test content.\n')
|
client.asserts.assertText(xpath=u'/html/body', validator=u'\nThis is some unique test content.\n')
|
||||||
client.open(url=u'http://localhost:8000/test_admin/admin/')
|
client.open(url=u'http://localhost:8000/test_admin/admin/')
|
||||||
client.waits.forPageLoad(timeout=u'8000')
|
client.waits.forPageLoad(timeout=u'8000')
|
||||||
|
client.click(link=u'Log out')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
|
||||||
|
|
||||||
|
def test_ensureLogout():
|
||||||
|
client = WindmillTestClient(calling_func_name())
|
||||||
|
|
||||||
|
client.open(url=ADMIN_URL)
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.open(url="%s/accounts/logout"% global_settings.TEST_URL)
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.asserts.assertText(xpath=u"//div[@id='content']/h1", validator=u'Logged out')
|
||||||
|
client.asserts.assertText(xpath=u"//div[@id='content']/p", validator=u'Thanks for spending some quality time with the Web site today.')
|
||||||
|
client.asserts.assertNode(link=u'Log in again')
|
@ -125,3 +125,23 @@ class AdminForeignKeyWidgetChangeList(DjangoTestCase):
|
|||||||
def test_changelist_foreignkey(self):
|
def test_changelist_foreignkey(self):
|
||||||
response = self.client.get('/widget_admin/admin_widgets/car/')
|
response = self.client.get('/widget_admin/admin_widgets/car/')
|
||||||
self.failUnless('/widget_admin/auth/user/add/' in response.content)
|
self.failUnless('/widget_admin/auth/user/add/' in response.content)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# import os
|
||||||
|
# from django.test import windmill_tests as djangotest
|
||||||
|
# #from windmill.authoring import djangotest
|
||||||
|
# #from windmill.conf import global_settings
|
||||||
|
#
|
||||||
|
# class TestProjectWindmillTest(djangotest.WindmillDjangoUnitTest):
|
||||||
|
# fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml', 'admin-views-unicode.xml',
|
||||||
|
# 'multiple-child-classes', 'admin-views-actions.xml', 'string-primary-key.xml', 'admin-views-person.xml']
|
||||||
|
# test_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'windmilltests')
|
||||||
|
# #test_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
# #test_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
# browser = 'firefox'
|
||||||
|
# test_url = 'http://localhost:8000/test_admin/admin/'
|
||||||
|
# #global_settings.TEST_URL = test_url
|
||||||
|
#
|
||||||
|
# # def test_tryout(self):
|
||||||
|
# # pass
|
||||||
|
128
tests/regressiontests/admin_widgets/wmtests/__init__.py
Normal file
128
tests/regressiontests/admin_widgets/wmtests/__init__.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
|
||||||
|
from windmill.conf import global_settings
|
||||||
|
ADMIN_WIDGET_URL = "%s/widget_admin/" % global_settings.TEST_URL
|
||||||
|
from windmill.authoring import WindmillTestClient
|
||||||
|
from django.test.utils import calling_func_name
|
||||||
|
|
||||||
|
|
||||||
|
def test_baseWidgetTestCars():
|
||||||
|
client = WindmillTestClient("A second module")
|
||||||
|
|
||||||
|
client.open(url=ADMIN_WIDGET_URL)
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.type(text=u'super', id=u'id_username')
|
||||||
|
client.type(text=u'secret', id=u'id_password')
|
||||||
|
client.click(value=u'Log in')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(link=u'Car tires', timeout=u'8000')
|
||||||
|
client.click(link=u'Car tires')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(link=u' Add car tire ', timeout=u'8000')
|
||||||
|
client.click(link=u' Add car tire ')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(timeout=u'8000', id=u'id_car')
|
||||||
|
client.click(id=u'id_car')
|
||||||
|
client.click(xpath=u"//a[@id='add_id_car']/img")
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(xpath=u"//form[@id='car_form']/div/fieldset/div[2]/div", timeout=u'8000')
|
||||||
|
client.click(xpath=u"//form[@id='car_form']/div/fieldset/div[2]/div")
|
||||||
|
client.click(id=u'id_owner')
|
||||||
|
client.select(option=u'super', id=u'id_owner')
|
||||||
|
client.click(value=u'100')
|
||||||
|
client.click(id=u'id_make')
|
||||||
|
client.type(text=u'Ferrari', id=u'id_make')
|
||||||
|
client.type(text=u'F-xx', id=u'id_model')
|
||||||
|
client.click(xpath=u"//form[@id='car_form']/div/fieldset/div[2]")
|
||||||
|
client.click(name=u'_save')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.closeWindow()
|
||||||
|
client.click(link=u'Home')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(link=u'Car tires', timeout=u'8000')
|
||||||
|
client.click(link=u'Car tires')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(link=u' Add car tire ', timeout=u'8000')
|
||||||
|
client.click(link=u' Add car tire ')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.select(option=u'Ferrari F-xx', id=u'id_car')
|
||||||
|
client.click(value=u'1')
|
||||||
|
client.click(name=u'_save')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(link=u'CarTire object', timeout=u'8000')
|
||||||
|
client.click(link=u'CarTire object')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.asserts.assertImageLoaded(xpath=u"//a[@id='add_id_car']/img")
|
||||||
|
client.asserts.assertNode(id=u'id_car')
|
||||||
|
client.asserts.assertNode(link=u'Delete')
|
||||||
|
client.click(xpath=u"//form[@id='cartire_form']/div/fieldset/div/div")
|
||||||
|
client.click(link=u'Home')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(link=u'Cars', timeout=u'8000')
|
||||||
|
client.click(link=u'Cars')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.asserts.assertImageLoaded(xpath=u"//a[@id='add_id_form-0-owner']/img")
|
||||||
|
client.asserts.assertNode(link=u'Ferrari')
|
||||||
|
client.asserts.assertNode(id=u'id_form-0-owner')
|
||||||
|
#client.asserts.assertSelected(xpath=u"//select[@id='id_form-0-owner']/option[3]", validator=u'')
|
||||||
|
client.click(link=u' Home ')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
client.waits.forElement(timeout=u'8000', id=u'user-tools')
|
||||||
|
client.click(id=u'user-tools')
|
||||||
|
client.click(link=u'Log out')
|
||||||
|
client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
|
||||||
|
def test_loginWidgetAdmin():
|
||||||
|
'''Mostly just a proof of concept to test working order of tests.'''
|
||||||
|
client = WindmillTestClient("freebie test")
|
||||||
|
|
||||||
|
# print dir(client)
|
||||||
|
# print dir(client.open)
|
||||||
|
# print dir(client.commands)
|
||||||
|
# print client.commands()
|
||||||
|
|
||||||
|
# client.open(url=ADMIN_URL)
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
# client.type(text=u'super', id=u'id_username')
|
||||||
|
# client.type(text=u'secret', id=u'id_password')
|
||||||
|
# client.click(value=u'Log in')
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
# client.asserts.assertNode(xpath=u"//div[@id='content-main']/div/table/tbody/tr[1]/th")
|
||||||
|
# client.asserts.assertNode(link=u'Articles')
|
||||||
|
# client.asserts.assertNode(link=u'Add')
|
||||||
|
# client.asserts.assertNode(link=u'Change')
|
||||||
|
# client.asserts.assertNode(link=u'Admin_Views')
|
||||||
|
# client.asserts.assertNode(xpath=u"//div[@id='user-tools']/strong")
|
||||||
|
# client.click(xpath=u"//div[@id='content-main']/div/table/tbody/tr[22]/td/a")
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
# client.type(text=u'Test Section', id=u'id_name')
|
||||||
|
# client.click(name=u'_save')
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
# client.asserts.assertNode(link=u'Section object')
|
||||||
|
# client.click(link=u' Admin_views ')
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
# client.waits.forElement(link=u'Add', timeout=u'8000')
|
||||||
|
# client.click(link=u'Add')
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
# client.type(text=u'Test 1', id=u'id_title')
|
||||||
|
# client.type(text=u'This is test content.', id=u'id_content')
|
||||||
|
# client.click(link=u'Today')
|
||||||
|
# client.click(link=u'Now')
|
||||||
|
# client.click(id=u'id_section')
|
||||||
|
# client.select(option=u'Section object', id=u'id_section')
|
||||||
|
# client.click(value=u'1')
|
||||||
|
# #client.asserts.assertValue(validator=u'2009-06-16', id=u'id_date_0')
|
||||||
|
# #client.asserts.assertValue(validator=u'13:31:21', id=u'id_date_1')
|
||||||
|
# client.asserts.assertNode(id=u'id_section')
|
||||||
|
# client.click(name=u'_save')
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
# client.asserts.assertNode(link=u'This is test content.')
|
||||||
|
# client.asserts.assertNode(xpath=u"//div[@id='changelist']/form/table/tbody/tr/td[2]")
|
||||||
|
# client.asserts.assertNode(xpath=u"//div[@id='changelist']/form/table/tbody/tr/td[3]")
|
||||||
|
# client.asserts.assertNode(xpath=u"//div[@id='changelist']/form/table/tbody/tr/td[4]")
|
||||||
|
# client.asserts.assertNode(xpath=u"//div[@id='changelist']/form/table/tbody/tr/td[5]")
|
||||||
|
# client.asserts.assertNode(xpath=u"//div[@id='changelist']/form/table/tbody/tr/th")
|
||||||
|
# client.click(link=u'Today')
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
||||||
|
# client.asserts.assertNode(xpath=u"//div[@id='changelist']/form/table/tbody/tr/th")
|
||||||
|
# client.click(link=u' Home ')
|
||||||
|
# client.waits.forPageLoad(timeout=u'20000')
|
@ -38,14 +38,14 @@ ALWAYS_INSTALLED_APPS = [
|
|||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
]
|
]
|
||||||
|
|
||||||
WINDMILL_FIXTURES = ['regressiontests/admin_views/fixtures/%s' % fix for fix in ['admin-views-users.xml',
|
# WINDMILL_FIXTURES = ['regressiontests/admin_views/fixtures/%s' % fix for fix in ['admin-views-users.xml',
|
||||||
'admin-views-colors.xml',
|
# 'admin-views-colors.xml',
|
||||||
'admin-views-fabrics.xml',
|
# 'admin-views-fabrics.xml',
|
||||||
'admin-views-unicode.xml',
|
# 'admin-views-unicode.xml',
|
||||||
'multiple-child-classes',
|
# 'multiple-child-classes',
|
||||||
'admin-views-actions.xml',
|
# 'admin-views-actions.xml',
|
||||||
'string-primary-key.xml',
|
# 'string-primary-key.xml',
|
||||||
'admin-views-person.xml']]
|
# 'admin-views-person.xml']]
|
||||||
|
|
||||||
|
|
||||||
def get_test_models():
|
def get_test_models():
|
||||||
@ -179,7 +179,7 @@ def django_tests(verbosity, interactive, test_labels):
|
|||||||
if not hasattr(settings, 'TEST_RUNNER'):
|
if not hasattr(settings, 'TEST_RUNNER'):
|
||||||
settings.TEST_RUNNER = 'django.test.simple.run_tests'
|
settings.TEST_RUNNER = 'django.test.simple.run_tests'
|
||||||
#establish coverage settings for the regression suite
|
#establish coverage settings for the regression suite
|
||||||
settings.COVERAGE_MODULE_EXCLUDES = ['modeltests*', 'regressiontests*']
|
settings.COVERAGE_MODULE_EXCLUDES = ['modeltests*', 'regressiontests*', 'from .* import .*', 'import .*',]
|
||||||
settings.COVERAGE_CODE_EXCLUDES = ['def __unicode__\(self\):', 'def get_absolute_url\(self\):']
|
settings.COVERAGE_CODE_EXCLUDES = ['def __unicode__\(self\):', 'def get_absolute_url\(self\):']
|
||||||
# depending on how this is run, we might need to tell the coverage libraries to consider django.*
|
# depending on how this is run, we might need to tell the coverage libraries to consider django.*
|
||||||
settings.COVERAGE_ADDITIONAL_MODULES = ['django']
|
settings.COVERAGE_ADDITIONAL_MODULES = ['django']
|
||||||
@ -226,37 +226,18 @@ def django_tests(verbosity, interactive, test_labels):
|
|||||||
else:
|
else:
|
||||||
global_settings.START_FIREFOX = True
|
global_settings.START_FIREFOX = True
|
||||||
|
|
||||||
|
#
|
||||||
# Create the threaded server.
|
|
||||||
server_container = ServerContainer()
|
|
||||||
# Set the server's 'fixtures' attribute so they can be loaded in-thread if using sqlite's memory backend.
|
|
||||||
server_container.__setattr__('fixtures', WINDMILL_FIXTURES)
|
|
||||||
# Start the server thread.
|
|
||||||
started = server_container.start_test_server()
|
|
||||||
|
|
||||||
print 'Waiting for threaded server to come online.'
|
|
||||||
started.wait()
|
|
||||||
print 'DB Ready, Server online.'
|
|
||||||
|
|
||||||
# These 2 unit tests can't be used while running our admin. Explicitly remove.
|
|
||||||
if 'regressiontests.bug8245' in settings.INSTALLED_APPS:
|
|
||||||
settings.INSTALLED_APPS.remove('regressiontests.bug8245')
|
|
||||||
if 'django.contrib.gis' in settings.INSTALLED_APPS:
|
|
||||||
settings.INSTALLED_APPS.remove('django.contrib.gis')
|
|
||||||
|
|
||||||
# Set the testing URL based on what available port we get.
|
|
||||||
global_settings.TEST_URL = 'http://localhost:%d' % server_container.server_thread.port
|
|
||||||
|
|
||||||
|
|
||||||
# Find which of our INSTALLED_APPS have tests.
|
# Find which of our INSTALLED_APPS have tests.
|
||||||
tests = []
|
tests = []
|
||||||
for name in [app for app in settings.INSTALLED_APPS if not('invalid' in app)]:
|
for name in [app for app in settings.INSTALLED_APPS if not('invalid' in app)]:
|
||||||
for suffix in ['tests', 'wmtests', 'windmilltests']:
|
for suffix in ['tests', 'wmtests', 'windmilltests']:
|
||||||
x = attempt_import(name, suffix)
|
x = attempt_import(name, suffix)
|
||||||
if x is not None:
|
if x is not None:
|
||||||
|
print "Adding %s %s to tests" % (suffix, x, )
|
||||||
tests.append((suffix, x, ))
|
tests.append((suffix, x, ))
|
||||||
|
|
||||||
# Collect the WindmillDjangoUnitTest from tests.py and any 'wmtests' or 'windmilltests' modules.
|
# Collect the WindmillDjangoUnitTest from tests.py and any 'wmtests' or 'windmilltests' modules.
|
||||||
|
wmfixs = []
|
||||||
wmtests = []
|
wmtests = []
|
||||||
for (ttype, mod, ) in tests:
|
for (ttype, mod, ) in tests:
|
||||||
if ttype == 'tests':
|
if ttype == 'tests':
|
||||||
@ -272,6 +253,33 @@ def django_tests(verbosity, interactive, test_labels):
|
|||||||
wmtests.append(os.path.join(*os.path.split(os.path.abspath(mod.__file__))[:-1]))
|
wmtests.append(os.path.join(*os.path.split(os.path.abspath(mod.__file__))[:-1]))
|
||||||
else:
|
else:
|
||||||
wmtests.append(os.path.abspath(mod.__file__))
|
wmtests.append(os.path.abspath(mod.__file__))
|
||||||
|
# Look for any attribute named fixtures and try to load it.
|
||||||
|
if hasattr(mod, 'fixtures'):
|
||||||
|
for fixture in getattr(mod, 'fixtures'):
|
||||||
|
wmfixs.append(fixture)
|
||||||
|
|
||||||
|
# Create the threaded server.
|
||||||
|
server_container = ServerContainer()
|
||||||
|
# Set the server's 'fixtures' attribute so they can be loaded in-thread if using sqlite's memory backend.
|
||||||
|
server_container.__setattr__('fixtures', wmfixs)
|
||||||
|
# Start the server thread.
|
||||||
|
started = server_container.start_test_server()
|
||||||
|
# These 2 unit tests can't be used while running our admin. Explicitly remove.
|
||||||
|
if 'regressiontests.bug8245' in settings.INSTALLED_APPS:
|
||||||
|
settings.INSTALLED_APPS.remove('regressiontests.bug8245')
|
||||||
|
if 'django.contrib.gis' in settings.INSTALLED_APPS:
|
||||||
|
settings.INSTALLED_APPS.remove('django.contrib.gis')
|
||||||
|
|
||||||
|
print 'Waiting for threaded server to come online.'
|
||||||
|
started.wait()
|
||||||
|
print 'DB Ready, Server online.'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Set the testing URL based on what available port we get.
|
||||||
|
global_settings.TEST_URL = 'http://localhost:%d' % server_container.server_thread.port
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Make sure we even need to run tests.
|
# Make sure we even need to run tests.
|
||||||
if len(wmtests) is 0:
|
if len(wmtests) is 0:
|
||||||
@ -280,16 +288,51 @@ def django_tests(verbosity, interactive, test_labels):
|
|||||||
# Setup and run unittests.
|
# Setup and run unittests.
|
||||||
testtotals = {}
|
testtotals = {}
|
||||||
x = logging.getLogger()
|
x = logging.getLogger()
|
||||||
x.setLevel(0)
|
x.setLevel(logging.DEBUG)
|
||||||
from windmill.server.proxy import logger
|
from windmill.server.proxy import logger
|
||||||
from functest import bin
|
#from functest import bin
|
||||||
from functest import runner
|
#from functest import runner
|
||||||
runner.CLIRunner.final = classmethod(lambda self, totals: testtotals.update(totals))
|
#runner.CLIRunner.final = classmethod(lambda self, totals: testtotals.update(totals))
|
||||||
import windmill
|
#import windmill
|
||||||
|
#count = 0
|
||||||
|
#print wmtests
|
||||||
|
#for wmt in wmtests:
|
||||||
|
#print wmt
|
||||||
|
#print tests[count][1]
|
||||||
|
#count = count + 1
|
||||||
|
#count = 0
|
||||||
|
bin = None
|
||||||
|
runner = None
|
||||||
setup_module(tests[0][1])
|
setup_module(tests[0][1])
|
||||||
sys.argv = wmtests
|
for wmt in wmtests:
|
||||||
bin.cli()
|
print sys.argv
|
||||||
|
sys.argv = [wmt,]
|
||||||
|
print sys.argv
|
||||||
|
for k in (k for k in sys.modules.keys() if k.startswith('functest')):
|
||||||
|
del(sys.modules[k])
|
||||||
|
#dbin)
|
||||||
|
#del(runner)
|
||||||
|
import functest
|
||||||
|
from functest import bin
|
||||||
|
from functest import runner
|
||||||
|
runner.CLIRunner.final = classmethod(lambda self, totals: testtotals.update(totals) )
|
||||||
|
bin.cli()
|
||||||
|
bin = None
|
||||||
|
runner = None
|
||||||
|
print sys.argv
|
||||||
|
# import functest
|
||||||
|
# functest.modules_passed = []
|
||||||
|
# functest.modules_failed = []
|
||||||
|
# from functest import frame
|
||||||
|
# frame.totals = {'pass':0, 'fail':0, 'skip':0}
|
||||||
|
#teardown_module(tests[count][1])
|
||||||
|
#sleep(.5)
|
||||||
|
#count = count + 1
|
||||||
|
#setup_module(tests[count][1])
|
||||||
teardown_module(tests[0][1])
|
teardown_module(tests[0][1])
|
||||||
|
# sys.argv = [wmtests[0],]
|
||||||
|
# bin.cli()
|
||||||
|
|
||||||
if testtotals['fail'] is not 0:
|
if testtotals['fail'] is not 0:
|
||||||
sleep(.5)
|
sleep(.5)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@ -340,3 +383,4 @@ if __name__ == "__main__":
|
|||||||
do_std = options.standard
|
do_std = options.standard
|
||||||
wm_browser = options.wmbrowser
|
wm_browser = options.wmbrowser
|
||||||
django_tests(int(options.verbosity), options.interactive, args)
|
django_tests(int(options.verbosity), options.interactive, args)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user