In our first post on Selenium in Python, we saw how to prepare your continuous integration environment on Debian. Now it's time to have a look on how to add Selenium tests in your existing web project.

Sample project This tutorial is based on the poll application from the Django tutorial. It describes all the required steps to run Selenium tests on a Django project. The source code can be found here. This sample project is organized as follow: The following features are implemented: Poll management via the Django admin site,

Vote submission. Don't forget to install Django! 1 pip install Django

Configure tests The test configuration is located in tests/setup.cfg and will be loaded by nose at runtime: with-xunit generates test result reports,

generates test result reports, with-coverage and cover-package generate coverage reports for the djangotutorial and polls packages,

and generate coverage reports for the and packages, with-django enables djangosanetesting which setup database for instance,

enables which setup database for instance, with-cherrypyliveserver starts a CherryPy server on djangotutorial for Selenium tests,

starts a CherryPy server on for Selenium tests, with-selenium-server starts a Selenium Server,

starts a Selenium Server, with-selenium-driver provides a Selenium Web Driver to the tests. The test database is configured in djangotutorial/settings.py with TEST_DATABASE_NAME (used by djangosanetesting for live server) and TEST_NAME : 1 TEST_DATABASE_NAME = 'djangotutorialtest.db' 2 DATABASES = { 3 'default' : { 4 'ENGINE' : 'django.db.backends.sqlite3' , 5 # Other configuration 6 # ... 7 'TEST_NAME' : TEST_DATABASE_NAME , 8 } 9 }

Write tests Selenium tests are located in the tests folder. Here is a test template: 1 from selenose.cases import SeleniumTestCase 2 3 from djangosanetesting.cases import HttpTestCase 4 5 class SampleTestCase ( SeleniumTestCase , HttpTestCase ): 6 7 def test ( self ): 8 self . driver . get ( 'http://localhost:8000/' ) 9 # Your test here... This test inherits from: selenose.cases.SeleniumTestCase to flag this test as a Selenium test for the Selenium Driver Plugin of selenose (the one providing a Web Driver),

to flag this test as a Selenium test for the Selenium Driver Plugin of selenose (the one providing a Web Driver), djangosanetesting.cases.HttpTestCase to flag this test as an HTTP test for djangosanetesting, to start the CherryPy server. Then write tests as usual, with the benefit of having the self.driver directly available. The following sections contain the test examples of two major features: vote submission,

login on admin site. Test vote submission The project defines a sample poll How is selenose? in the djangotutorial/polls/fixtures/initial_data.json fixture which is loaded at database initialization. This test verifies that the voting process is working for this poll: 1 class PollsTestCase ( SeleniumTestCase , HttpTestCase ): 2 3 def test_vote ( self ): 4 self . driver . get ( 'http://localhost:8000/polls/' ) 5 poll = self . driver . find_element_by_link_text ( 'How is selenose?' ) 6 poll . click () 7 time . sleep ( 2 ) # Should use accurate WebDriverWait 8 choices = self . driver . find_elements_by_name ( 'choice' ) 9 self . assertEquals ( 2 , len ( choices )) 10 choices [ 1 ] . click () 11 choices [ 1 ] . submit () 12 lis = self . driver . find_elements_by_tag_name ( 'li' ) 13 self . assertEquals ( 2 , len ( lis )) 14 self . assertEquals ( 'Cool? -- 0 votes' , lis [ 0 ] . text ) 15 self . assertEquals ( 'Super cool? -- 1 vote' , lis [ 1 ] . text ) First open the page listing the polls: http://localhost:8000/polls/ ,

, Search the link pointing to the How is selenose? poll, and click on it,

poll, and click on it, Verify that two choices are available, then select the last one before submitting the form,

Finally verify the vote results on the poll result page. Test admin site login The project also defines an administrator admin/admin in the djangotutorial/polls/fixtures/initial_data.json fixture which is loaded at database initialization. This test checks that the admin user can log into the admin site: 1 class AdminTestCase ( SeleniumTestCase , HttpTestCase ): 2 3 def test_login ( self ): 4 self . driver . get ( 'http://localhost:8000/admin/' ) 5 self . driver . find_element_by_id ( 'id_username' ) . send_keys ( 'admin' ) 6 password = self . driver . find_element_by_id ( 'id_password' ) 7 password . send_keys ( 'admin' ) 8 password . submit () 9 time . sleep ( 2 ) # Should use accurate WebDriverWait 10 self . assertTrue ( self . driver . find_element_by_id ( 'user-tools' ) . text . startswith ( 'Welcome' )) First open the administration interface login page: http://localhost:8000/admin/ ,

, Then look for the field dedicated to username (has an id id_username ) and type admin ,

) and type , Then look for the field dedicated to password (has an id id_password ) and type admin before submitting the form,

) and type before submitting the form, Finally assert that the user is welcomed.

Run tests The script tests/run.py is the entry point to run the tests. It: Adds / (folder of the project) and /djangotutorial (for polls module) in the sys.path ,

(folder of the project) and (for module) in the , Exports the DJANGO_SETTINGS_MODULE in os.environ to define the Django settings module to use in tests,

in to define the Django settings module to use in tests, Changes the current directory to the tests folder,

folder, Call nose. To run all tests with the firefox Web Driver environment (see selenose documentation for more information on Web Driver environments), execute: 1 $ python tests/run.py --selenium-driver = firefox Or to run a single test: 1 $ python tests/run.py --selenium-driver = firefox test_admin.py