Revamp of testing machinery.

* Uses Django 1.4 as minimum version for Folsom.
  * Switches to using Django 1.4's LiveServerTestCase instead of
    django-nose-selenium and cherrypy.
  * Moves django-nose to be a test dependency only. Fixes bug 801362.

Change-Id: I5c8a145aba868acf355fe215307d7ce8835913f6
This commit is contained in:
Gabriel Hurley 2012-04-11 14:04:08 -07:00
parent 13a356e0ed
commit a2e7b10918
9 changed files with 55 additions and 57 deletions

View File

@ -59,6 +59,8 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
'horizon.context_processors.horizon') 'horizon.context_processors.horizon')
STATIC_URL = '/static/'
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
ROOT_URLCONF = 'horizon.tests.testurls' ROOT_URLCONF = 'horizon.tests.testurls'
@ -72,11 +74,12 @@ NOSE_ARGS = ['--nocapture',
'--nologcapture', '--nologcapture',
'--cover-package=horizon', '--cover-package=horizon',
'--cover-inclusive'] '--cover-inclusive']
# For nose-selenium integration
LIVE_SERVER_PORT = 8000
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
SESSION_COOKIE_HTTPONLY = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_SECURE = False
HORIZON_CONFIG = { HORIZON_CONFIG = {
'dashboards': ('nova', 'syspanel', 'settings',), 'dashboards': ('nova', 'syspanel', 'settings',),

View File

@ -22,7 +22,7 @@
URL patterns for testing Horizon views. URL patterns for testing Horizon views.
""" """
from django.conf.urls.defaults import * from django.conf.urls.defaults import patterns, url, include
import horizon import horizon

View File

@ -94,19 +94,20 @@ INSTALLED_APPS = (
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django_nose',
'horizon', 'horizon',
'horizon.dashboards.nova', 'horizon.dashboards.nova',
'horizon.dashboards.syspanel', 'horizon.dashboards.syspanel',
'horizon.dashboards.settings', 'horizon.dashboards.settings',
) )
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',) AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
SESSION_COOKIE_HTTPONLY = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_SECURE = False
TIME_ZONE = None TIME_ZONE = None
gettext_noop = lambda s: s gettext_noop = lambda s: s
LANGUAGES = ( LANGUAGES = (
@ -123,12 +124,7 @@ LANGUAGES = (
LANGUAGE_CODE = 'en' LANGUAGE_CODE = 'en'
USE_I18N = True USE_I18N = True
ACCOUNT_ACTIVATION_DAYS = 7
TOTAL_CLOUD_RAM_GB = 10
OPENSTACK_KEYSTONE_DEFAULT_ROLE = 'Member' OPENSTACK_KEYSTONE_DEFAULT_ROLE = 'Member'
LIVE_SERVER_PORT = 8000
try: try:
from local.local_settings import * from local.local_settings import *
@ -137,13 +133,3 @@ except ImportError:
if DEBUG: if DEBUG:
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
try:
import debug_toolbar
INSTALLED_APPS += ('debug_toolbar',)
MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',)
except ImportError:
_logger = logging.getLogger(__name__)
_logger.debug('Running in debug mode without debug_toolbar.')

View File

View File

@ -0,0 +1,11 @@
import os
from horizon.tests.testsettings import *
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_PATH = os.path.abspath(os.path.join(TEST_DIR, ".."))
ROOT_URLCONF = 'openstack_dashboard.urls'
TEMPLATE_DIRS = (os.path.join(ROOT_PATH, 'templates'),)
STATICFILES_DIRS = (os.path.join(ROOT_PATH, 'static'),)
INSTALLED_APPS += ('openstack_dashboard',)

View File

@ -1,13 +1,33 @@
import os
from django import test from django import test
from noseselenium.cases import SeleniumTestCaseMixin from django.utils import unittest
from selenium.webdriver.firefox.webdriver import WebDriver
class SeleniumTests(test.TestCase, SeleniumTestCaseMixin): @unittest.skipUnless(os.environ.get('WITH_SELENIUM', False),
"The WITH_SELENIUM env variable is not set.")
class SeleniumTests(test.LiveServerTestCase):
@classmethod
def setUpClass(cls):
if os.environ.get('WITH_SELENIUM', False):
cls.selenium = WebDriver()
super(SeleniumTests, cls).setUpClass()
@classmethod
def tearDownClass(cls):
super(SeleniumTests, cls).tearDownClass()
if os.environ.get('WITH_SELENIUM', False):
cls.selenium.quit()
def test_splash(self): def test_splash(self):
self.selenium.open("/") self.selenium.get(self.live_server_url)
self.failUnless(self.selenium.is_text_present("User Name")) button = self.selenium.find_element_by_tag_name("button")
self.assertEqual(button.text, "Sign In")
def test_qunit(self): def test_qunit(self):
self.selenium.open("/qunit/") self.selenium.get("%s%s" % (self.live_server_url, "/qunit/")),
self.selenium.wait_for_page_to_load("2000") self.selenium.implicitly_wait("1000")
self.failUnless(self.selenium.is_text_present("0 failed")) failed = self.selenium.find_element_by_class_name("failed")
self.assertEqual(int(failed.text), 0)

View File

@ -6,7 +6,7 @@ set -o errexit
# Increment me any time the environment should be rebuilt. # Increment me any time the environment should be rebuilt.
# This includes dependncy changes, directory renames, etc. # This includes dependncy changes, directory renames, etc.
# Simple integer secuence: 1, 2, 3... # Simple integer secuence: 1, 2, 3...
environment_version=14 environment_version=15
#--------------------------------------------------------# #--------------------------------------------------------#
function usage { function usage {
@ -201,13 +201,6 @@ function sanity_check {
exit 1 exit 1
fi fi
fi fi
if [ $selenium -eq 1 ]; then
SELENIUM_JOB=`ps -elf | grep "selenium" | grep -v grep`
if [ $? -eq 0 ]; then
echo "WARNING: Selenium doesn't appear to be running. Please start a selenium server process."
selenium=0
fi
fi
# Remove .pyc files. This is sanity checking because they can linger # Remove .pyc files. This is sanity checking because they can linger
# after old files are deleted. # after old files are deleted.
find . -name "*.pyc" -exec rm -rf {} \; find . -name "*.pyc" -exec rm -rf {} \;
@ -276,10 +269,9 @@ function run_tests {
echo "Running openstack_dashboard tests" echo "Running openstack_dashboard tests"
if [ $selenium -eq 1 ]; then if [ $selenium -eq 1 ]; then
${command_wrapper} coverage run -p $root/manage.py test openstack_dashboard --settings=horizon.tests.testsettings --with-selenium --with-cherrypyliveserver $testargs export WITH_SELENIUM=1
else
${command_wrapper} coverage run -p $root/manage.py test openstack_dashboard --settings=horizon.tests.testsettings $testargs
fi fi
${command_wrapper} coverage run -p $root/manage.py test openstack_dashboard --settings=openstack_dashboard.test.settings $testargs
# get results of the openstack_dashboard tests # get results of the openstack_dashboard tests
DASHBOARD_RESULT=$? DASHBOARD_RESULT=$?

View File

@ -1,21 +1,7 @@
# Horizon Core Requirements # Horizon Core Requirements
Django>=1.3 Django>=1.4
python-cloudfiles python-cloudfiles
python-dateutil python-dateutil
django-nose
# Glance Requirements
PasteDeploy
eventlet
kombu
paste
pycrypto==2.3
routes
sqlalchemy
sqlalchemy-migrate
webob==1.0.8
xattr
iso8601
# Horizon Non-pip Requirements # Horizon Non-pip Requirements
-e git+https://github.com/openstack/python-novaclient.git#egg=python-novaclient -e git+https://github.com/openstack/python-novaclient.git#egg=python-novaclient

View File

@ -1,12 +1,12 @@
# Testing Requirements # Testing Requirements
CherryPy
coverage coverage
django-nose-selenium django-nose
mox mox
nose nose
pep8 pep8
pylint pylint
distribute>=0.6.24 distribute>=0.6.24
selenium
# Docs Requirements # Docs Requirements
sphinx sphinx