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:
parent
13a356e0ed
commit
a2e7b10918
@ -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',),
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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.')
|
|
||||||
|
0
openstack_dashboard/test/__init__.py
Normal file
0
openstack_dashboard/test/__init__.py
Normal file
11
openstack_dashboard/test/settings.py
Normal file
11
openstack_dashboard/test/settings.py
Normal 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',)
|
@ -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)
|
||||||
|
14
run_tests.sh
14
run_tests.sh
@ -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=$?
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user