diff --git a/django/core/management/commands/test_windmill.py b/django/core/management/commands/test_windmill.py index 406083c739..27352e3438 100644 --- a/django/core/management/commands/test_windmill.py +++ b/django/core/management/commands/test_windmill.py @@ -5,25 +5,26 @@ import sys, os from time import sleep import types import logging +import threading class ServerContainer(object): start_test_server = djangotest.start_test_server stop_test_server = djangotest.stop_test_server def attempt_import(name, suffix): - try: - mod = __import__(name+'.'+suffix) - except ImportError: - mod = None - if mod is not None: - s = name.split('.') - mod = __import__(s.pop(0)) - for x in s+[suffix]: - try: - mod = getattr(mod, x) - except Exception, e: - pass - return mod + try: + mod = __import__(name+'.'+suffix) + except ImportError: + mod = None + if mod is not None: + s = name.split('.') + mod = __import__(s.pop(0)) + for x in s+[suffix]: + try: + mod = getattr(mod, x) + except Exception, e: + pass + return mod class Command(BaseCommand): @@ -54,14 +55,6 @@ class Command(BaseCommand): sys.argv.remove('manage.py') if 'test_windmill' in sys.argv: 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 tests = [] @@ -69,7 +62,7 @@ class Command(BaseCommand): for suffix in ['tests', 'wmtests', 'windmilltests']: x = attempt_import(name, suffix) if x is not None: tests.append((suffix,x,)); - + wmfixs = [] wmtests = [] for (ttype, mod,) in 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])) else: 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: print 'Sorry, no windmill tests found.' diff --git a/docs/howto/index.txt b/docs/howto/index.txt index 1a27a2ebac..214f36e47f 100644 --- a/docs/howto/index.txt +++ b/docs/howto/index.txt @@ -25,6 +25,7 @@ you quickly accomplish common tasks. outputting-csv outputting-pdf static-files + windmill-tests .. seealso:: diff --git a/docs/howto/windmill-tests.txt b/docs/howto/windmill-tests.txt new file mode 100644 index 0000000000..08931d8a97 --- /dev/null +++ b/docs/howto/windmill-tests.txt @@ -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. diff --git a/docs/index.txt b/docs/index.txt index 89ee463dfa..abf5580c60 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -142,7 +142,9 @@ The development process :ref:`Overview ` | :ref:`Adding custom commands ` - * **Testing:** :ref:`Overview ` + * **Testing:** + :ref:`Overview ` | + :ref:`Windmill ` * **Deployment:** :ref:`Overview ` | diff --git a/docs/ref/index.txt b/docs/ref/index.txt index 6cc796d8e4..3ffa1fcce1 100644 --- a/docs/ref/index.txt +++ b/docs/ref/index.txt @@ -20,4 +20,3 @@ API Reference signals templates/index unicode - diff --git a/docs/topics/testing.txt b/docs/topics/testing.txt index 1256a61187..2a01df9e87 100644 --- a/docs/topics/testing.txt +++ b/docs/topics/testing.txt @@ -400,7 +400,7 @@ Some of the things you can do with the test client are: a template context that contains certain values. 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: * 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* 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, ` +Windmill_. Details on integrating Windmill tests with Django are available +:ref:`here. ` .. _Twill: http://twill.idyll.org/ -.. _Selenium: http://www.openqa.org/selenium/ +.. _Windmill: http://www.getwindmill.com/ Overview and a quick example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index f2ffbe8c2f..ffc1d91fd1 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -1420,23 +1420,23 @@ class AdminInlineTests(TestCase): self.failUnlessEqual(FancyDoodad.objects.count(), 1) self.failUnlessEqual(FancyDoodad.objects.all()[0].name, "Fancy Doodad 1 Updated") -import os -#from django.test import windmill_tests as djangotest -#from windmill.authoring import djangotest -#from windmill.conf import global_settings - +# 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'] +# '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 +# #global_settings.TEST_URL = test_url +# +# # def test_tryout(self): +# # pass diff --git a/tests/regressiontests/admin_views/windmilltests/__init__.py b/tests/regressiontests/admin_views/windmilltests/__init__.py index 05bddd2a27..9f87a74cdb 100644 --- a/tests/regressiontests/admin_views/windmilltests/__init__.py +++ b/tests/regressiontests/admin_views/windmilltests/__init__.py @@ -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 # from django.test import windmill_tests as djangotest # #from windmill.authoring import djangotest @@ -5,6 +14,7 @@ from windmill.conf import global_settings ADMIN_URL = "%s/test_admin/admin" % global_settings.TEST_URL #ADMIN_URL = 'http://localhost:8000/test_admin/admin/' +#['regressiontests/admin_views/fixtures/%s' % fix for fix in ] # # class TestProjectWindmillTest(djangotest.WindmillDjangoUnitTest): @@ -21,11 +31,15 @@ ADMIN_URL = "%s/test_admin/admin" % global_settings.TEST_URL # # pass # 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(): '''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.open) @@ -83,7 +97,7 @@ def test_loginAndSetup(): def test_changeListNamingLinkingHistory(): '''Creating a Model with strings for pk, and checking history.''' - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) client.waits.forPageLoad(timeout=u'20000') # client.open(url=ADMIN_URL) @@ -118,7 +132,7 @@ def test_changeListNamingLinkingHistory(): def test_filtersSearchOnChangeList(): '''Testing Updates and Filters/Search on Person Models''' - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) client.waits.forPageLoad(timeout=u'20000') @@ -165,7 +179,7 @@ def test_filtersSearchOnChangeList(): def test_defaultDeleteAdminAction(): '''Admin Actions test. Test the default delete action.''' - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) client.waits.forPageLoad(timeout=u'20000') @@ -180,7 +194,7 @@ def test_defaultDeleteAdminAction(): client.asserts.assertNode(link=u'Horizontal') def test_dateTimeModelsandWidgets(): - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) client.waits.forPageLoad(timeout=u'20000') @@ -250,7 +264,7 @@ def test_dateTimeModelsandWidgets(): client.waits.forPageLoad(timeout=u'20000') def test_inlineEditandCreate(): - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) client.waits.forPageLoad(timeout=u'20000') @@ -276,7 +290,7 @@ def test_inlineEditandCreate(): def test_adminActionEmptyModels(): - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) client.waits.forPageLoad(timeout=u'20000') @@ -339,7 +353,7 @@ def test_adminActionEmptyModels(): client.waits.forPageLoad(timeout=u'20000') def test_parentChildRelationship(): - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) client.waits.forPageLoad(timeout=u'20000') @@ -374,7 +388,7 @@ def test_parentChildRelationship(): client.waits.forPageLoad(timeout=u'20000') def test_AdminAuthContrib(): - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) client.waits.forPageLoad(timeout=u'20000') @@ -423,7 +437,7 @@ def test_AdminAuthContrib(): def test_contribFlatSitesRedirect(): - client = WindmillTestClient(__name__) + client = WindmillTestClient(calling_func_name()) client.open(url=ADMIN_URL) 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.open(url=u'http://localhost:8000/test_admin/admin/') 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') \ No newline at end of file diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py index 55088ca1fe..69bc54e33a 100644 --- a/tests/regressiontests/admin_widgets/tests.py +++ b/tests/regressiontests/admin_widgets/tests.py @@ -125,3 +125,23 @@ class AdminForeignKeyWidgetChangeList(DjangoTestCase): def test_changelist_foreignkey(self): response = self.client.get('/widget_admin/admin_widgets/car/') 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 diff --git a/tests/regressiontests/admin_widgets/wmtests/__init__.py b/tests/regressiontests/admin_widgets/wmtests/__init__.py new file mode 100644 index 0000000000..572975ffa3 --- /dev/null +++ b/tests/regressiontests/admin_widgets/wmtests/__init__.py @@ -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') \ No newline at end of file diff --git a/tests/runtests.py b/tests/runtests.py index 7980ec128f..e73d076277 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -38,14 +38,14 @@ ALWAYS_INSTALLED_APPS = [ 'django.contrib.admin', ] -WINDMILL_FIXTURES = ['regressiontests/admin_views/fixtures/%s' % fix for fix in ['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']] +# WINDMILL_FIXTURES = ['regressiontests/admin_views/fixtures/%s' % fix for fix in ['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']] def get_test_models(): @@ -179,7 +179,7 @@ def django_tests(verbosity, interactive, test_labels): if not hasattr(settings, 'TEST_RUNNER'): settings.TEST_RUNNER = 'django.test.simple.run_tests' #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\):'] # depending on how this is run, we might need to tell the coverage libraries to consider django.* settings.COVERAGE_ADDITIONAL_MODULES = ['django'] @@ -226,37 +226,18 @@ def django_tests(verbosity, interactive, test_labels): else: 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. tests = [] for name in [app for app in settings.INSTALLED_APPS if not('invalid' in app)]: for suffix in ['tests', 'wmtests', 'windmilltests']: x = attempt_import(name, suffix) if x is not None: + print "Adding %s %s to tests" % (suffix, x, ) tests.append((suffix, x, )) # Collect the WindmillDjangoUnitTest from tests.py and any 'wmtests' or 'windmilltests' modules. + wmfixs = [] wmtests = [] for (ttype, mod, ) in 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])) else: 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. if len(wmtests) is 0: @@ -280,16 +288,51 @@ def django_tests(verbosity, interactive, test_labels): # Setup and run unittests. testtotals = {} x = logging.getLogger() - x.setLevel(0) + x.setLevel(logging.DEBUG) from windmill.server.proxy import logger - from functest import bin - from functest import runner - runner.CLIRunner.final = classmethod(lambda self, totals: testtotals.update(totals)) - import windmill + #from functest import bin + #from functest import runner + #runner.CLIRunner.final = classmethod(lambda self, totals: testtotals.update(totals)) + #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]) - sys.argv = wmtests - bin.cli() + for wmt in wmtests: + 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]) + # sys.argv = [wmtests[0],] + # bin.cli() + if testtotals['fail'] is not 0: sleep(.5) sys.exit(1) @@ -340,3 +383,4 @@ if __name__ == "__main__": do_std = options.standard wm_browser = options.wmbrowser django_tests(int(options.verbosity), options.interactive, args) +