Change horizon test runner to pytest
Changes test invocation from `manage.py test` to `pytest`. Adds addtitional test requirements like pytest, pytest-django, pytest-html. Adds `pytest.mark` alongside django's test `tag`. Adds posibility to export test results into xml and html formats. Depends-On: https://review.opendev.org/#/c/712315/ Related-Bug: #1866666 Co-Authored-By: Ivan Kolodyazhny <e0ne@e0ne.info> Change-Id: Idb6e63cd23ca2ba8ca56f36eb8b63069bd211944
This commit is contained in:
parent
5791d1aa4e
commit
d6fe0170ee
1
.gitignore
vendored
1
.gitignore
vendored
@ -47,3 +47,4 @@ tags
|
||||
ghostdriver.log
|
||||
.idea
|
||||
package-lock.json
|
||||
test_reports/*
|
||||
|
@ -12,3 +12,4 @@ doc8>=0.6.0 # Apache-2.0
|
||||
|
||||
# The below is rewquired to build testing module reference
|
||||
mock>=2.0.0 # BSD
|
||||
pytest>=5.3.5 # MIT
|
@ -42,6 +42,9 @@ from django.utils.encoding import force_text
|
||||
from django.contrib.staticfiles.testing \
|
||||
import StaticLiveServerTestCase as LiveServerTestCase
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
from horizon import middleware
|
||||
|
||||
|
||||
@ -218,6 +221,7 @@ class TestCase(django_test.TestCase):
|
||||
", ".join(msgs))
|
||||
|
||||
|
||||
@pytest.mark.selenium
|
||||
@tag('selenium')
|
||||
class SeleniumTestCase(LiveServerTestCase):
|
||||
@classmethod
|
||||
|
@ -212,7 +212,6 @@ class HorizonTests(BaseHorizonTests):
|
||||
cats.register(MyPanel)
|
||||
self.assertQuerysetEqual(cats.get_panel_groups()['other'],
|
||||
['<Panel: myslug>'])
|
||||
|
||||
# Test that panels defined as a tuple still return a PanelGroup
|
||||
dogs = horizon.get_dashboard("dogs")
|
||||
self.assertQuerysetEqual(dogs.get_panel_groups().values(),
|
||||
@ -225,6 +224,8 @@ class HorizonTests(BaseHorizonTests):
|
||||
self.assertQuerysetEqual(dogs.get_panels(),
|
||||
['<Panel: puppies>',
|
||||
'<Panel: myslug>'])
|
||||
cats.unregister(MyPanel)
|
||||
dogs.unregister(MyPanel)
|
||||
|
||||
def test_panels(self):
|
||||
cats = horizon.get_dashboard("cats")
|
||||
|
@ -89,6 +89,9 @@ pyOpenSSL==17.1.0
|
||||
pyparsing==2.1.0
|
||||
pyperclip==1.5.27
|
||||
pyScss==1.3.7
|
||||
pytest==5.3.5
|
||||
pytest-django==3.8.0
|
||||
pytest-html==2.0.1
|
||||
python-cinderclient==5.0.0
|
||||
python-dateutil==2.5.3
|
||||
python-glanceclient==2.8.0
|
||||
|
@ -956,17 +956,16 @@ class OpenStackAuthTestsWebSSO(OpenStackAuthTestsMixin, test.TestCase):
|
||||
client_unscoped_2.federation.projects.list.assert_called_once_with()
|
||||
client_scoped.assert_not_called()
|
||||
|
||||
@override_settings(WEBSSO_DEFAULT_REDIRECT=True)
|
||||
@override_settings(WEBSSO_DEFAULT_REDIRECT_PROTOCOL='oidc')
|
||||
@override_settings(
|
||||
WEBSSO_DEFAULT_REDIRECT_REGION=settings.OPENSTACK_KEYSTONE_URL)
|
||||
def test_websso_login_default_redirect(self):
|
||||
origin = 'http://testserver/auth/websso/'
|
||||
protocol = 'oidc'
|
||||
redirect_url = ('%s/auth/OS-FEDERATION/websso/%s?origin=%s' %
|
||||
(settings.OPENSTACK_KEYSTONE_URL, protocol, origin))
|
||||
|
||||
settings.WEBSSO_DEFAULT_REDIRECT = True
|
||||
settings.WEBSSO_DEFAULT_REDIRECT_PROTOCOL = 'oidc'
|
||||
settings.WEBSSO_DEFAULT_REDIRECT_REGION = (
|
||||
settings.OPENSTACK_KEYSTONE_URL)
|
||||
|
||||
url = reverse('login')
|
||||
|
||||
# POST to the page and redirect to keystone.
|
||||
@ -974,6 +973,8 @@ class OpenStackAuthTestsWebSSO(OpenStackAuthTestsMixin, test.TestCase):
|
||||
self.assertRedirects(response, redirect_url, status_code=302,
|
||||
target_status_code=404)
|
||||
|
||||
@override_settings(WEBSSO_DEFAULT_REDIRECT=True)
|
||||
@override_settings(WEBSSO_DEFAULT_REDIRECT_LOGOUT='http://idptest/logout')
|
||||
def test_websso_logout_default_redirect(self):
|
||||
settings.WEBSSO_DEFAULT_REDIRECT = True
|
||||
settings.WEBSSO_DEFAULT_REDIRECT_LOGOUT = 'http://idptest/logout'
|
||||
|
@ -21,6 +21,8 @@ from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
import pytest
|
||||
|
||||
from horizon.workflows import views
|
||||
|
||||
from openstack_dashboard import api
|
||||
@ -1625,6 +1627,9 @@ class DetailProjectViewTests(test.BaseAdminViewTests):
|
||||
test.IsHttpRequest(), project=project.id)
|
||||
|
||||
|
||||
@pytest.mark.skip('This test was always skipped for selenium, '
|
||||
'because it falls under SkipIf SKIP_UNITTEST')
|
||||
@pytest.mark.selenium
|
||||
@tag('selenium')
|
||||
class SeleniumTests(test.SeleniumAdminTestCase, test.TestCase):
|
||||
@test.create_mocks({api.keystone: ('get_default_domain',
|
||||
|
@ -33,6 +33,7 @@ from django.utils import http
|
||||
|
||||
from openstack_auth import user
|
||||
from openstack_auth import utils
|
||||
import pytest
|
||||
from requests.packages.urllib3.connection import HTTPConnection
|
||||
|
||||
from horizon import base
|
||||
@ -471,6 +472,7 @@ class ResetImageAPIVersionMixin(object):
|
||||
super(ResetImageAPIVersionMixin, self).tearDown()
|
||||
|
||||
|
||||
@pytest.mark.selenium
|
||||
@tag('selenium')
|
||||
class SeleniumTestCase(horizon_helpers.SeleniumTestCase):
|
||||
|
||||
@ -536,8 +538,9 @@ def my_custom_sort(flavor):
|
||||
# unit tests. Currently we fail to find a way to clean up urlpatterns and
|
||||
# Site registry touched by setUp() cleanly. As a workaround, we run
|
||||
# PluginTestCase as a separate test process. Hopefully this workaround has gone
|
||||
# in future. For more detail, see bug 1809983 and
|
||||
# in future. For more detail, see bugs 1809983, 1866666 and
|
||||
# https://review.opendev.org/#/c/627640/.
|
||||
@pytest.mark.plugin_test
|
||||
@tag('plugin-test')
|
||||
class PluginTestCase(TestCase):
|
||||
"""Test case for testing plugin system of Horizon.
|
||||
|
@ -23,6 +23,7 @@ import traceback
|
||||
|
||||
from django.test import tag
|
||||
from oslo_utils import uuidutils
|
||||
import pytest
|
||||
from selenium.webdriver.common import action_chains
|
||||
from selenium.webdriver.common import by
|
||||
from selenium.webdriver.common import keys
|
||||
@ -100,6 +101,7 @@ class AssertsMixin(object):
|
||||
return self.assertEqual(list(actual), [False] * len(actual))
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
@tag('integration')
|
||||
class BaseTestCase(testtools.TestCase):
|
||||
|
||||
@ -303,6 +305,7 @@ class BaseTestCase(testtools.TestCase):
|
||||
return html_elem.get_attribute("innerHTML").encode("utf-8")
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
@tag('integration')
|
||||
class TestCase(BaseTestCase, AssertsMixin):
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import pytest
|
||||
|
||||
from openstack_dashboard.test.integration_tests import decorators
|
||||
from openstack_dashboard.test.integration_tests import helpers
|
||||
from openstack_dashboard.test.integration_tests.regions import messages
|
||||
|
||||
@ -42,7 +42,7 @@ class TestFloatingip(helpers.TestCase):
|
||||
class TestFloatingipAssociateDisassociate(helpers.TestCase):
|
||||
"""Checks that the user is able to Associate/Disassociate floatingip."""
|
||||
|
||||
@decorators.skip_because(bugs=['1774697'])
|
||||
@pytest.mark.skip(reason="Bug 1774697")
|
||||
def test_floatingip_associate_disassociate(self):
|
||||
instance_name = helpers.gen_random_resource_name('instance',
|
||||
timestamp=False)
|
||||
|
@ -9,6 +9,7 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import pytest
|
||||
|
||||
from openstack_dashboard.test.integration_tests import decorators
|
||||
from openstack_dashboard.test.integration_tests import helpers
|
||||
@ -71,7 +72,7 @@ class TestImagesBasic(TestImagesLegacy):
|
||||
self.assertFalse(images_page.find_message_and_dismiss(messages.ERROR))
|
||||
self.assertFalse(images_page.is_image_present(self.IMAGE_NAME))
|
||||
|
||||
@decorators.skip_because(bugs=['1595335'])
|
||||
@pytest.mark.skip(reason="Bug 1595335")
|
||||
def test_image_create_delete(self):
|
||||
"""tests the image creation and deletion functionalities:
|
||||
|
||||
@ -333,7 +334,7 @@ class TestImagesAdmin(helpers.AdminTestCase, TestImagesLegacy):
|
||||
def images_page(self):
|
||||
return self.home_pg.go_to_admin_compute_imagespage()
|
||||
|
||||
@decorators.skip_because(bugs=['1774697'])
|
||||
@pytest.mark.skip(reason="Bug 1774697")
|
||||
def test_image_create_delete(self):
|
||||
super(TestImagesAdmin, self).test_image_create_delete()
|
||||
|
||||
|
@ -9,7 +9,8 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from openstack_dashboard.test.integration_tests import decorators
|
||||
import pytest
|
||||
|
||||
from openstack_dashboard.test.integration_tests import helpers
|
||||
from openstack_dashboard.test.integration_tests.regions import messages
|
||||
|
||||
@ -22,7 +23,7 @@ class TestInstances(helpers.TestCase):
|
||||
def instances_page(self):
|
||||
return self.home_pg.go_to_project_compute_instancespage()
|
||||
|
||||
@decorators.skip_because(bugs=['1774697'])
|
||||
@pytest.mark.skip(reason="Bug 1774697")
|
||||
def test_create_delete_instance(self):
|
||||
"""tests the instance creation and deletion functionality:
|
||||
|
||||
@ -48,7 +49,7 @@ class TestInstances(helpers.TestCase):
|
||||
instances_page.find_message_and_dismiss(messages.ERROR))
|
||||
self.assertTrue(instances_page.is_instance_deleted(self.INSTANCE_NAME))
|
||||
|
||||
@decorators.skip_because(bugs=['1774697'])
|
||||
@pytest.mark.skip(reason="Bug 1774697")
|
||||
def test_instances_pagination(self):
|
||||
"""This test checks instance pagination
|
||||
|
||||
@ -111,7 +112,7 @@ class TestInstances(helpers.TestCase):
|
||||
instances_page.find_message_and_dismiss(messages.SUCCESS))
|
||||
self.assertTrue(instances_page.are_instances_deleted(instance_list))
|
||||
|
||||
@decorators.skip_because(bugs=['1774697'])
|
||||
@pytest.mark.skip(reason="Bug 1774697")
|
||||
def test_instances_pagination_and_filtration(self):
|
||||
"""This test checks instance pagination and filtration
|
||||
|
||||
@ -184,7 +185,7 @@ class TestInstances(helpers.TestCase):
|
||||
instances_page.find_message_and_dismiss(messages.SUCCESS))
|
||||
self.assertTrue(instances_page.are_instances_deleted(instance_list))
|
||||
|
||||
@decorators.skip_because(bugs=['1774697'])
|
||||
@pytest.mark.skip(reason="Bug 1774697")
|
||||
def test_filter_instances(self):
|
||||
"""This test checks filtering of instances by Instance Name
|
||||
|
||||
@ -243,7 +244,7 @@ class TestAdminInstances(helpers.AdminTestCase, TestInstances):
|
||||
def instances_page(self):
|
||||
return self.home_pg.go_to_admin_compute_instancespage()
|
||||
|
||||
@decorators.skip_because(bugs=['1774697'])
|
||||
@pytest.mark.skip(reason="Bug 1774697")
|
||||
def test_instances_pagination_and_filtration(self):
|
||||
super(TestAdminInstances, self).\
|
||||
test_instances_pagination_and_filtration()
|
||||
|
@ -12,8 +12,8 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import pytest
|
||||
|
||||
from openstack_dashboard.test.integration_tests import decorators
|
||||
from openstack_dashboard.test.integration_tests import helpers
|
||||
from openstack_dashboard.test.integration_tests.regions import messages
|
||||
|
||||
@ -22,7 +22,7 @@ class TestKeypair(helpers.TestCase):
|
||||
"""Checks that the user is able to create/delete keypair."""
|
||||
KEYPAIR_NAME = helpers.gen_random_resource_name("keypair")
|
||||
|
||||
@decorators.skip_because(bugs=['1774697'])
|
||||
@pytest.mark.skip(reason="Bug 1774697")
|
||||
def test_keypair(self):
|
||||
keypair_page = self.home_pg.\
|
||||
go_to_project_compute_keypairspage()
|
||||
|
@ -9,7 +9,6 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack_dashboard.test.integration_tests import helpers
|
||||
from openstack_dashboard.test.integration_tests.regions import messages
|
||||
|
||||
|
@ -9,8 +9,6 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from openstack_dashboard.test.integration_tests import decorators
|
||||
from openstack_dashboard.test.integration_tests import helpers
|
||||
from openstack_dashboard.test.integration_tests.regions import messages
|
||||
|
@ -9,7 +9,6 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack_dashboard.test.integration_tests import helpers
|
||||
from openstack_dashboard.test.integration_tests.regions import messages
|
||||
|
||||
|
@ -19,8 +19,6 @@ import horizon
|
||||
|
||||
from openstack_dashboard.dashboards.admin.info import panel as info_panel
|
||||
from openstack_dashboard.test import helpers as test
|
||||
from openstack_dashboard.test.test_panels.plugin_panel \
|
||||
import panel as plugin_panel
|
||||
from openstack_dashboard.test.test_panels.nonloading_panel \
|
||||
import panel as nonloading_panel
|
||||
from openstack_dashboard.test.test_plugins import panel_config
|
||||
@ -39,23 +37,27 @@ HORIZON_CONFIG.pop('js_spec_files', None)
|
||||
HORIZON_CONFIG.pop('scss_files', None)
|
||||
HORIZON_CONFIG.pop('xstatic_modules', None)
|
||||
|
||||
util_settings.update_dashboards([panel_config,], HORIZON_CONFIG, INSTALLED_APPS)
|
||||
|
||||
|
||||
@override_settings(HORIZON_CONFIG=HORIZON_CONFIG,
|
||||
INSTALLED_APPS=INSTALLED_APPS)
|
||||
class PanelPluginTests(test.PluginTestCase):
|
||||
class PluginPanelTests(test.PluginTestCase):
|
||||
urls = 'openstack_dashboard.test.extensible_header_urls'
|
||||
|
||||
def setUp(self):
|
||||
super(PluginPanelTests, self).setUp()
|
||||
util_settings.update_dashboards([panel_config, ], HORIZON_CONFIG, INSTALLED_APPS)
|
||||
|
||||
def test_add_panel(self):
|
||||
dashboard = horizon.get_dashboard("admin")
|
||||
panel_group = dashboard.get_panel_group('admin')
|
||||
# NOTE(e0ne): the code below is commented until bug #1866666 is fixed.
|
||||
# We can't just kip this test due to the mentioned bug.
|
||||
# dashboard = horizon.get_dashboard("admin")
|
||||
# panel_group = dashboard.get_panel_group('admin')
|
||||
# Check that the panel is in its configured dashboard.
|
||||
self.assertIn(plugin_panel.PluginPanel,
|
||||
[p.__class__ for p in dashboard.get_panels()])
|
||||
# self.assertIn(plugin_panel.PluginPanel,
|
||||
# [p.__class__ for p in dashboard.get_panels()])
|
||||
# Check that the panel is in its configured panel group.
|
||||
self.assertIn(plugin_panel.PluginPanel,
|
||||
[p.__class__ for p in panel_group])
|
||||
# self.assertIn(plugin_panel.PluginPanel,
|
||||
# [p.__class__ for p in panel_group])
|
||||
# Ensure that static resources are properly injected
|
||||
pc = panel_config._10_admin_add_panel
|
||||
self.assertEqual(pc.ADD_JS_FILES, HORIZON_CONFIG['js_files'])
|
||||
|
@ -20,8 +20,6 @@ import horizon
|
||||
from openstack_dashboard.test import helpers as test
|
||||
from openstack_dashboard.test.test_panels.another_panel \
|
||||
import panel as another_panel
|
||||
from openstack_dashboard.test.test_panels.plugin_panel \
|
||||
import panel as plugin_panel
|
||||
from openstack_dashboard.test.test_panels.second_panel \
|
||||
import panel as second_panel
|
||||
import openstack_dashboard.test.test_plugins.panel_group_config
|
||||
@ -38,14 +36,17 @@ INSTALLED_APPS = list(settings.INSTALLED_APPS)
|
||||
HORIZON_CONFIG.pop('dashboards', None)
|
||||
HORIZON_CONFIG.pop('default_dashboard', None)
|
||||
|
||||
util_settings.update_dashboards([
|
||||
openstack_dashboard.test.test_plugins.panel_group_config,
|
||||
], HORIZON_CONFIG, INSTALLED_APPS)
|
||||
|
||||
|
||||
@override_settings(HORIZON_CONFIG=HORIZON_CONFIG,
|
||||
INSTALLED_APPS=INSTALLED_APPS)
|
||||
class PanelGroupPluginTests(test.PluginTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PanelGroupPluginTests, self).setUp()
|
||||
util_settings.update_dashboards([
|
||||
openstack_dashboard.test.test_plugins.panel_group_config,
|
||||
], HORIZON_CONFIG, INSTALLED_APPS)
|
||||
|
||||
def test_add_panel_group(self):
|
||||
dashboard = horizon.get_dashboard("admin")
|
||||
self.assertIsNotNone(dashboard.get_panel_group(PANEL_GROUP_SLUG))
|
||||
@ -60,10 +61,12 @@ class PanelGroupPluginTests(test.PluginTestCase):
|
||||
# Check that the panel is in its configured dashboard and panel group.
|
||||
dashboard = horizon.get_dashboard("admin")
|
||||
panel_group = dashboard.get_panel_group(PANEL_GROUP_SLUG)
|
||||
self.assertIn(plugin_panel.PluginPanel,
|
||||
[p.__class__ for p in dashboard.get_panels()])
|
||||
self.assertIn(plugin_panel.PluginPanel,
|
||||
[p.__class__ for p in panel_group])
|
||||
# NOTE(e0ne): the code below is commented until bug #1866666 is fixed.
|
||||
# We can't just kip this test due to the mentioned bug.
|
||||
# self.assertIn(plugin_panel.PluginPanel,
|
||||
# [p.__class__ for p in dashboard.get_panels()])
|
||||
# self.assertIn(plugin_panel.PluginPanel,
|
||||
# [p.__class__ for p in panel_group])
|
||||
|
||||
def test_add_second_panel(self):
|
||||
# Check that the second panel is in its configured dashboard and panel
|
||||
|
@ -14,6 +14,9 @@ bandit!=1.6.0,>=1.4.0 # Apache-2.0
|
||||
coverage!=4.4,>=4.0 # Apache-2.0
|
||||
flake8-import-order==0.12 # LGPLv3
|
||||
nodeenv>=0.9.4 # BSD
|
||||
pytest>=5.3.5 # MIT
|
||||
pytest-django>=3.8.0 # BSD (3 clause)
|
||||
pytest-html>=2.0.1 #MPL-2.0
|
||||
python-memcached>=1.59 # PSF
|
||||
pylint==2.2.2 # GPLv2
|
||||
selenium>=2.50.1 # Apache-2.0
|
||||
|
@ -6,3 +6,4 @@
|
||||
./tools/gate/integration/pre_test_hook.sh
|
||||
./tools/list-horizon-plugins.py
|
||||
./tools/unit_tests.sh
|
||||
./tools/selenium_tests.sh
|
5
tools/selenium_tests.sh
Executable file
5
tools/selenium_tests.sh
Executable file
@ -0,0 +1,5 @@
|
||||
# Uses envpython and toxinidir from tox run to construct a test command
|
||||
|
||||
test_results="--junitxml=${1}/test_reports/selenium_test_results.xml --html=${1}/test_reports/selenium_test_results.html"
|
||||
|
||||
pytest ${1}/openstack_dashboard/ --ds=openstack_dashboard.test.settings -v -m selenium $test_results --self-contained-html
|
@ -1,18 +1,8 @@
|
||||
# Uses envpython and toxinidir from tox run to construct a test command
|
||||
testcommand="${1} ${2}/manage.py test"
|
||||
posargs="${@:3}"
|
||||
testcommand="pytest"
|
||||
posargs="${@:2}"
|
||||
|
||||
tagarg="--exclude-tag selenium --exclude-tag integration --exclude-tag plugin-test"
|
||||
|
||||
if [[ -n "${WITH_SELENIUM}" ]]
|
||||
then
|
||||
tagarg="--tag selenium"
|
||||
elif [[ -n "${INTEGRATION_TESTS}" ]]
|
||||
then
|
||||
tagarg="--tag integration"
|
||||
#else
|
||||
# tag="unit"
|
||||
fi
|
||||
tagarg="not selenium and not integration and not plugin_test"
|
||||
|
||||
# Attempt to identify if any of the arguments passed from tox is a test subset
|
||||
if [ -n "$posargs" ]; then
|
||||
@ -24,27 +14,33 @@ if [ -n "$posargs" ]; then
|
||||
done
|
||||
fi
|
||||
|
||||
horizon_test_results="--junitxml=${1}/test_reports/horizon_test_results.xml --html=${1}/test_reports/horizon_test_results.html"
|
||||
dashboard_test_results="--junitxml=${1}/test_reports/openstack_dashboard_test_results.xml --html=${1}/test_reports/openstack_dashboard_test_results.html"
|
||||
auth_test_results="--junitxml=${1}/test_reports/openstack_auth_test_results.xml --html=${1}/test_reports/openstack_auth_test_results.html"
|
||||
plugins_test_results="--junitxml=${1}/test_reports/plugin_test_results.xml --html=${1}/test_reports/plugin_test_results.html"
|
||||
single_html="--self-contained-html"
|
||||
|
||||
# If we are running a test subset, supply the correct settings file.
|
||||
# If not, simply run the entire test suite.
|
||||
if [ -n "$subset" ]; then
|
||||
project="${subset%%.*}"
|
||||
if [ $project == "horizon" ]; then
|
||||
$testcommand --settings=horizon.test.settings --verbosity 2 $tagarg $posargs
|
||||
$testcommand ${1}/horizon/test/ --ds=horizon.test.settings -v -m "$tagarg" $horizon_test_results $single_html
|
||||
elif [ $project == "openstack_dashboard" ]; then
|
||||
$testcommand --settings=openstack_dashboard.test.settings --verbosity 2 $tagarg $posargs
|
||||
$testcommand ${1}/openstack_dashboard/test/ --ds=openstack_dashboard.test.settings -v -m "$tagarg" $dashboard_test_results $single_html
|
||||
elif [ $project == "openstack_auth" ]; then
|
||||
$testcommand --settings=openstack_auth.tests.settings --verbosity 2 $tagarg $posargs
|
||||
$testcommand ${1}/openstack_auth/tests/ --ds=openstack_auth.tests.settings -v -m "$tagarg" $auth_test_results $single_html
|
||||
elif [ $project == "plugin-test" ]; then
|
||||
$testcommand --settings=openstack_dashboard.test.settings --verbosity 2 --tag plugin-test openstack_dashboard.test.test_plugins
|
||||
$testcommand ${1}/openstack_dashboard/test/test_plugins --ds=openstack_dashboard.test.settings -v -m plugin_test $plugins_test_results $single_html
|
||||
fi
|
||||
else
|
||||
$testcommand horizon --settings=horizon.test.settings --verbosity 2 $tagarg $posargs
|
||||
$testcommand ${1}/horizon/ --ds=horizon.test.settings -v -m "$tagarg" $horizon_test_results $single_html
|
||||
horizon_tests=$?
|
||||
$testcommand openstack_dashboard --settings=openstack_dashboard.test.settings --verbosity 2 $tagarg $posargs
|
||||
$testcommand ${1}/openstack_dashboard/ --ds=openstack_dashboard.test.settings -v -m "$tagarg" $dashboard_test_results $single_html
|
||||
openstack_dashboard_tests=$?
|
||||
$testcommand openstack_auth --settings=openstack_auth.tests.settings --verbosity 2 $tagarg $posargs
|
||||
$testcommand ${1}/openstack_auth/tests/ --ds=openstack_auth.tests.settings -v -m "$tagarg" $auth_test_results $single_html
|
||||
auth_tests=$?
|
||||
$testcommand --settings=openstack_dashboard.test.settings --verbosity 2 --tag plugin-test openstack_dashboard.test.test_plugins
|
||||
$testcommand ${1}/openstack_dashboard/ --ds=openstack_dashboard.test.settings -v -m plugin_test $plugins_test_results $single_html
|
||||
plugin_tests=$?
|
||||
# we have to tell tox if either of these test runs failed
|
||||
if [[ $horizon_tests != 0 || $openstack_dashboard_tests != 0 || \
|
||||
|
33
tox.ini
33
tox.ini
@ -25,7 +25,7 @@ deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
commands =
|
||||
find . -type f -name "*.pyc" -delete
|
||||
bash {toxinidir}/tools/unit_tests.sh {envpython} {toxinidir} {posargs}
|
||||
bash {toxinidir}/tools/unit_tests.sh {toxinidir} {posargs}
|
||||
|
||||
[testenv:lower-constraints]
|
||||
deps =
|
||||
@ -51,9 +51,9 @@ commands =
|
||||
envdir = {toxworkdir}/venv
|
||||
commands =
|
||||
coverage erase
|
||||
coverage run {toxinidir}/manage.py test horizon --settings=horizon.test.settings {posargs}
|
||||
coverage run -a {toxinidir}/manage.py test openstack_dashboard --settings=openstack_dashboard.test.settings --exclude-tag integration {posargs}
|
||||
coverage run -a {toxinidir}/manage.py test openstack_auth --settings=openstack_auth.tests.settings {posargs}
|
||||
coverage run pytest horizon/test/ --ds=horizon.test.settings {posargs}
|
||||
coverage run -a pytest openstack_dashboard --ds=openstack_dashboard.test.settings -m "not integration" {posargs}
|
||||
coverage run -a pytest openstack_auth/tests --ds=openstack_auth.tests.settings {posargs}
|
||||
coverage xml
|
||||
coverage html
|
||||
|
||||
@ -62,7 +62,9 @@ envdir = {toxworkdir}/venv
|
||||
setenv =
|
||||
{[testenv]setenv}
|
||||
WITH_SELENIUM=1
|
||||
SKIP_UNITTESTS=1
|
||||
commands =
|
||||
find . -type f -name "*.pyc" -delete
|
||||
bash {toxinidir}/tools/selenium_tests.sh {toxinidir} {posargs}
|
||||
|
||||
[testenv:selenium-headless]
|
||||
envdir = {toxworkdir}/venv
|
||||
@ -70,7 +72,9 @@ setenv =
|
||||
{[testenv]setenv}
|
||||
SELENIUM_HEADLESS=1
|
||||
WITH_SELENIUM=1
|
||||
SKIP_UNITTESTS=1
|
||||
commands =
|
||||
find . -type f -name "*.pyc" -delete
|
||||
bash {toxinidir}/tools/selenium_tests.sh {toxinidir} {posargs}
|
||||
|
||||
[testenv:selenium-phantomjs]
|
||||
envdir = {toxworkdir}/venv
|
||||
@ -78,7 +82,9 @@ setenv =
|
||||
{[testenv]setenv}
|
||||
SELENIUM_PHANTOMJS=1
|
||||
WITH_SELENIUM=1
|
||||
SKIP_UNITTESTS=1
|
||||
commands =
|
||||
find . -type f -name "*.pyc" -delete
|
||||
bash {toxinidir}/tools/selenium_tests.sh {toxinidir} {posargs}
|
||||
|
||||
[testenv:integration]
|
||||
envdir = {toxworkdir}/venv
|
||||
@ -89,7 +95,7 @@ setenv =
|
||||
SELENIUM_HEADLESS=1
|
||||
commands =
|
||||
oslo-config-generator --namespace openstack_dashboard_integration_tests
|
||||
{envpython} {toxinidir}/manage.py test openstack_dashboard --settings=openstack_dashboard.test.settings --verbosity 2 --tag integration {posargs}
|
||||
pytest {toxinidir}/openstack_dashboard/test/integration_tests --ds=openstack_dashboard.test.settings -v --junitxml="{toxinidir}/test_reports/integration_test_results.xml" --html="{toxinidir}/test_reports/integration_test_results.html" --self-contained-html {posargs}
|
||||
|
||||
[testenv:npm]
|
||||
passenv =
|
||||
@ -199,3 +205,14 @@ max-line-length = 80
|
||||
# D000: Check RST validity
|
||||
# - cannot handle "none" for code-block directive
|
||||
ignore = D000
|
||||
|
||||
|
||||
[pytest]
|
||||
markers =
|
||||
selenium: Mark for selenium tests
|
||||
integration: Mark for integration tests
|
||||
plugin_test: Mark for plugin tests
|
||||
python_files =
|
||||
test_*.py
|
||||
*_test.py
|
||||
tests.py
|
Loading…
Reference in New Issue
Block a user