-
Notifications
You must be signed in to change notification settings - Fork 31
Selenium Tests
[Selenium] (http://seleniumhq.org/) is an environment for browser-based regression tests. It simulates a user's interaction with the META-SHARE web application and provides means to verify the expected behavior of the application.
The following settings are required in local_settings.py
:
-
SELENIUM_DRIVER: This defines the browser against which the tests are run. The browser needs to be installed on the machine where the tests run. Supported browsers are Firefox, InternetExplorer, Opera and Chrome.
-
SELENIUM_TESTSERVER_PORT: This sets the port used for the Selenium test server. This must be the same port used in DJANGO_URL.
-
TEST_NAME entry in the default database: This is only required when using sqlite3 as engine. When not set, SQLite runs the tests in a memory based database. This does NOT work with Selenium tests. Therefore a file system based test database has to be set via the TEST_NAME entry. Be aware that a file based test database is much slower than a memory based one. So if you don't plan to run Selenium tests regularly on your local machine, you might want to omit the TEST_NAME entry and only activate it when running Selenium tests. If you use another engine apart from sqlite3, the TEST_NAME entry is not required.
-
DEBUG: This must be set to
true
, otherwise required static content (CSS, jQuery, ...) is NOT delivered properly and Selenium tests may rely on them.
The Selenium integration in META-SHARE extends the test command with two additional options:
manage.py test --selenium
runs the both the Selenium and non-Selenium tests.
manage.py test --selenium-only
runs only the Selenium tests.
manage.py test
runs the non-Selenium tests.
Additionally, the command for running Jenkins tests now runs both the Selenium and non-Selenium tests and creates the corresponding reports required for the Jenkins continuous integration:
manage.py jenkins
[Selenium IDE] (http://seleniumhq.org/projects/ide/) is a Firefox plugin that allows to easily record a user's interaction with a web application and to define assert statements about the results of the interaction. For more details, see the [documentation] (http://seleniumhq.org/docs/02_selenium_ide.html). The Selenium script can be exported to a number of formats. For META-SHARE, use 'Export Test Case As Python 2 (WebDriver)'.
To produce META-SHARE tests that run (almost) without any further modification, the Python 2 (WebDriver) format has to be adapted. This is done via
Options - Options... - Formats - Python 2 (WebDriver)
Please change the following entries:
####Header:
from django_selenium.testcases import SeleniumTestCase
from metashare import settings
from metashare.settings import DJANGO_BASE
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
class ${className}(SeleniumTestCase):
def setUp(self):
# init Selenium
driver = getattr(webdriver, settings.SELENIUM_DRIVER, None)
assert driver, "settings.SELENIUM_DRIVER contains non-existing driver"
self.driver = driver()
self.driver.implicitly_wait(30)
host = getattr(settings, 'SELENIUM_TESTSERVER_HOST', 'localhost')
port = getattr(settings, 'SELENIUM_TESTSERVER_PORT', 8000)
self.base_url = 'http://{0}:{1}/{2}'.format(host, port, DJANGO_BASE)
self.verificationErrors = []
def ${methodName}(self):
${receiver} = self.driver
####Footer:
def is_element_present(self, how, what):
try:
self.driver.find_element(by=how, value=what)
except NoSuchElementException:
return False
return True
def tearDown(self):
# clean up Selenium
self.driver.quit()
self.assertEqual([], self.verificationErrors)
After exporting to Python 2 (WebDriver) the only adaptation required is replacing
driver.get(self.base_url + "/whatever")
with
driver.get(self.base_url)
This is required because the base url is already adapted to the DJANGO_BASE in the setUp
method.
As with the other unit tests, the setUp
method can be extended to load fixture, define users, etc.
Be aware that a few assert/verify commands available in the IDE are currently not supported when exporting a test to Python 2 (WebDriver) (e.g. assertTextPresent
and verifyTextPresent
). If a command is not available,
the following line is inserted in the exported script:
# ERROR: Caught exception [ERROR: Unsupported command [...]]
If a command is not available, there is usually an alternative command to assert the same fact.
The final Selenium test has to be placed in a package named seltests
(parallel to the tests
package with the other unit tests). Don't forget to import your tests in seltests/__init__.py
An example Selenium test can be found in metashare/repo2/seltests/test_example.py
The windows navigation created by the Selenium IDE is currently not supported:
# ERROR: Caught exception [ERROR: Unsupported command [waitForPopUp]]
# ERROR: Caught exception [ERROR: Unsupported command [selectWindow]]
To change to a new window, use driver.switch_to_window("window-id")
. The id of a popup windows is displayed with the command in the Selenium IDE. After closing a popup window, use the same command to navigate to back to the original window. To return to the main window, its id should be stored in a variable:
root_id = driver.current_window_handle
...
driver.switch_to_window(root_id)
For debugging, its useful to create screenshots of the browser window during testing. This is done with
driver.get_screenshot_as_file('absolut-path-to-png')
A good location for screenshots is a dedicated folder in META-SHARE/metashare/reports
, e.g. for the test_LR_creation_corpus_text
test in seltests/test_editor
, the screenshots are saved in
META-SHARE/metashare/reports/PNG-metashare.repository.seltests.test_editor.EditorTest/LR_creation_corpus_text
META-SHARE/metashare/repository/seltests/test_utils.py
provides a number of utility methods for Selenium tests:
-
User login from the META-SHARE start page:
login_user(driver, user_name, user_passwd)
-
Simulation of a mouse hover event for a web element:
mouse_over(driver, web_ele)