| 1 | ========================================= |
|---|
| 2 | eduCommons $$version$$ SeleniumRC Testing |
|---|
| 3 | ========================================= |
|---|
| 4 | |
|---|
| 5 | :Title: eduCommons SeleniumRC Testing |
|---|
| 6 | :Author: Santiago Suarez Ordoñez <santiycr @ gmail..com> |
|---|
| 7 | :Copyright: This document has been placed in the public domain. |
|---|
| 8 | |
|---|
| 9 | .. contents:: |
|---|
| 10 | |
|---|
| 11 | Introduction |
|---|
| 12 | ------------- |
|---|
| 13 | |
|---|
| 14 | This guide aims to help people writing and |
|---|
| 15 | running tests using the Selenium RC environment and framework |
|---|
| 16 | built within eduCommons. |
|---|
| 17 | |
|---|
| 18 | Tests buildout |
|---|
| 19 | -------------- |
|---|
| 20 | |
|---|
| 21 | Originally, the test environment is not being |
|---|
| 22 | deployed within the production buildout. |
|---|
| 23 | To create an instance in which the tests can be |
|---|
| 24 | executed, you should run the buildout using the |
|---|
| 25 | test.cfg configuration:: |
|---|
| 26 | |
|---|
| 27 | $ ./bin/buildout -c tests.cfg |
|---|
| 28 | |
|---|
| 29 | Once the buildout is complete, a test runner script should |
|---|
| 30 | be located inside the bin folder and a new clean instance will be |
|---|
| 31 | created and prepared to run the tests. |
|---|
| 32 | |
|---|
| 33 | .. Note:: |
|---|
| 34 | |
|---|
| 35 | The plone zope instance tu use for the tests will be stored in a |
|---|
| 36 | sepparate ZODB to ensure integrity on any production instance. |
|---|
| 37 | |
|---|
| 38 | Running the tests |
|---|
| 39 | ----------------- |
|---|
| 40 | |
|---|
| 41 | To run the suite of tests buldled with eduCommons, the first thing to do after |
|---|
| 42 | the tests buildout has been run is to prepare an eduCommons site to test (if the the |
|---|
| 43 | user doesn't have a Plone site to test, yet). |
|---|
| 44 | For this to be done, you must first wake up the instance:: |
|---|
| 45 | |
|---|
| 46 | ./bin/instance start |
|---|
| 47 | |
|---|
| 48 | And then go to the ZMI and follow the procedure of creating an eduCommons Plone site. |
|---|
| 49 | Once the site is ready, the user should setup the different user accounts that the tests |
|---|
| 50 | will use. This accounts should have the following roles and passwords: |
|---|
| 51 | |
|---|
| 52 | ==== ========= ========= |
|---|
| 53 | Role Username Password |
|---|
| 54 | ==== ========= ========= |
|---|
| 55 | admin/manager admin test1234 |
|---|
| 56 | producer producer producer |
|---|
| 57 | reviewer reviewer reviewer |
|---|
| 58 | qa quality quality |
|---|
| 59 | publisher publisher publisher |
|---|
| 60 | viewer viewer viewer |
|---|
| 61 | ======= ========= ========= |
|---|
| 62 | |
|---|
| 63 | Once the instance and the eduCommons test site are ready, the user can run the tests. |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | The seleniumrunner script |
|---|
| 67 | +++++++++++++++++++++++++ |
|---|
| 68 | |
|---|
| 69 | The selenium runner is a scipt created to find and run **selenium tests** |
|---|
| 70 | for a product. |
|---|
| 71 | It receives different parameters and it's main objective is to simplify the |
|---|
| 72 | tests execution and reporting procedure. |
|---|
| 73 | This script will wake-up the selenium RC server, search and run the tests |
|---|
| 74 | and then shutdown the server and report the tests result. |
|---|
| 75 | |
|---|
| 76 | Basic tests execution |
|---|
| 77 | +++++++++++++++++++++ |
|---|
| 78 | |
|---|
| 79 | To run all the selenium tests for a product (e.g. eduCommons) |
|---|
| 80 | the user should pass at least two parameters: |
|---|
| 81 | |
|---|
| 82 | -i instance |
|---|
| 83 | The Plone site's name. This is defaulted to "educommons". |
|---|
| 84 | |
|---|
| 85 | -s product |
|---|
| 86 | The product in which the runner will search for tests to run. |
|---|
| 87 | |
|---|
| 88 | An example test execution will be:: |
|---|
| 89 | |
|---|
| 90 | $ ./bin/seleniumrunner -i educommonsSite -s enpraxis.educommons |
|---|
| 91 | |
|---|
| 92 | This will search all the **selenium** tests for the educommons product and |
|---|
| 93 | run them on http://localhost:<port_used>/educommonsSite. |
|---|
| 94 | |
|---|
| 95 | For running a particular test, the -t parameter should be passed to the runner:: |
|---|
| 96 | |
|---|
| 97 | $ ./bin/seleniumrunner -i educommonsSite -s enpraxis.educommons -t createPage |
|---|
| 98 | |
|---|
| 99 | .. Note:: |
|---|
| 100 | |
|---|
| 101 | Please notice that the createPage.py test should be stored in the |
|---|
| 102 | respective location and added to the __init__py file (See `Creating a test`_) |
|---|
| 103 | |
|---|
| 104 | Additional parameters |
|---|
| 105 | +++++++++++++++++++++ |
|---|
| 106 | |
|---|
| 107 | -p port |
|---|
| 108 | Set the port in which Selenium server will communicate |
|---|
| 109 | with the tests. |
|---|
| 110 | The default if 4444. |
|---|
| 111 | |
|---|
| 112 | |
|---|
| 113 | -b browser |
|---|
| 114 | Set the browser that will be used to run the tests. |
|---|
| 115 | **Note**: The tests written to ignore this will still |
|---|
| 116 | run using another browser. See the -f parameter to force |
|---|
| 117 | these tests to run on a specified browser. |
|---|
| 118 | The default value is: "\*firefox", but any browser supported |
|---|
| 119 | by selenium can be used ("\*iexplore", "\*opera", even |
|---|
| 120 | "\*firefox /path/to/firefox-bin"). |
|---|
| 121 | |
|---|
| 122 | -f |
|---|
| 123 | Force all the tests to use the desired browser. |
|---|
| 124 | |
|---|
| 125 | -o |
|---|
| 126 | Generate an HTML output as a summary of the results. |
|---|
| 127 | |
|---|
| 128 | for more details on this, please run:: |
|---|
| 129 | |
|---|
| 130 | $ ./bin/seleniumrunner -h |
|---|
| 131 | |
|---|
| 132 | Creating a test |
|---|
| 133 | --------------- |
|---|
| 134 | |
|---|
| 135 | The seleniumrunner script will look for all the classes that inherit from |
|---|
| 136 | unittest.TestCase on a specified package or module located under this kind of |
|---|
| 137 | path:: |
|---|
| 138 | |
|---|
| 139 | namespace.product/namespace/product/tests/seleniumtests |
|---|
| 140 | |
|---|
| 141 | .. Note:: |
|---|
| 142 | Notice that for adding tests to educommons' selenium tests, the path to add |
|---|
| 143 | the tests will end up being:: |
|---|
| 144 | |
|---|
| 145 | src/enpraxis.educommons/enpraxis/educommons/tests/seleniumtests |
|---|
| 146 | |
|---|
| 147 | Once the test script has been added to the tests location, it should be |
|---|
| 148 | included in the run by adding an import of the test in the *__init__.py* |
|---|
| 149 | file located in the same directory:: |
|---|
| 150 | |
|---|
| 151 | src/enpraxis.educommons/enpraxis/educommons/tests/seleniumtests/__init__.py |
|---|
| 152 | |
|---|
| 153 | |
|---|
| 154 | For a test to be correctly executed by the seleniumrunner script, |
|---|
| 155 | it must follow certain basic rules. |
|---|
| 156 | |
|---|
| 157 | Tests development guidelines |
|---|
| 158 | ++++++++++++++++++++++++++++ |
|---|
| 159 | |
|---|
| 160 | To create a test, there are certain basic rules to follow: |
|---|
| 161 | |
|---|
| 162 | #) The test should inherit from unittest.TestCase class (this can be done |
|---|
| 163 | indirectly also). |
|---|
| 164 | #) The test should use certain global variables for the code to work |
|---|
| 165 | on different environments and eduCommons instances. These are: |
|---|
| 166 | |
|---|
| 167 | - browser: For the browser used for the tests |
|---|
| 168 | |
|---|
| 169 | - port: For the port used to communicate with the server |
|---|
| 170 | |
|---|
| 171 | - url: For the url of the application under test |
|---|
| 172 | |
|---|
| 173 | - instance: The Plone site name (this depends on |
|---|
| 174 | the name used for the site's creation). |
|---|
| 175 | This variables should never be changed inside the test code, as the |
|---|
| 176 | seleniumrunner script will set them on runtime according with the parameters |
|---|
| 177 | received. |
|---|
| 178 | #) The selenium client driver used should be seleniumWrapper instead of |
|---|
| 179 | the classic selenium.py that's installed with the recipe (we will go |
|---|
| 180 | deeper on this later_). |
|---|
| 181 | |
|---|
| 182 | All this rules can be seen applied to the following `Example test`_. |
|---|
| 183 | |
|---|
| 184 | Example test |
|---|
| 185 | ++++++++++++ |
|---|
| 186 | |
|---|
| 187 | The following is an example test, it can be used as the basic |
|---|
| 188 | structure for future tests:: |
|---|
| 189 | |
|---|
| 190 | from seleniumWrapper import selenium |
|---|
| 191 | import unittest |
|---|
| 192 | |
|---|
| 193 | class NewTest(unittest.TestCase): |
|---|
| 194 | def setUp(self): |
|---|
| 195 | self.verificationErrors = [] |
|---|
| 196 | self.selenium = selenium("localhost", port, browser, url, instance) |
|---|
| 197 | self.selenium.start() |
|---|
| 198 | |
|---|
| 199 | def test_new(self): |
|---|
| 200 | sel = self.selenium |
|---|
| 201 | sel.login("admin","test1234") |
|---|
| 202 | # Do specific tests in here |
|---|
| 203 | |
|---|
| 204 | def tearDown(self): |
|---|
| 205 | self.selenium.stop() |
|---|
| 206 | self.assertEqual([], self.verificationErrors) |
|---|
| 207 | |
|---|
| 208 | Notice that the test doesn't have much changes from the basic |
|---|
| 209 | test exported using `Selenium IDE <http://seleniumhq.org/projects/ide/>`_, |
|---|
| 210 | the firefox extension. The only differences are the import of the eduCommons |
|---|
| 211 | wrapper instead of the standard selenium driver and the variables used for the |
|---|
| 212 | instanciation inside the *setUp* method. |
|---|
| 213 | |
|---|
| 214 | .. Note:: |
|---|
| 215 | |
|---|
| 216 | Please notice that the "instance" variable will have to be used in |
|---|
| 217 | each *open* command for the users to provide the correct location |
|---|
| 218 | of the eduCommons plone site to test. |
|---|
| 219 | |
|---|
| 220 | .. _later: |
|---|
| 221 | |
|---|
| 222 | The seleniumWrapper module |
|---|
| 223 | ++++++++++++++++++++++++++ |
|---|
| 224 | |
|---|
| 225 | This module is (as it's name says) a wrapper for the selenium standard lib. |
|---|
| 226 | The reason why we created it is to make tests clean and easier to maintain |
|---|
| 227 | by centralizing commonly used code. |
|---|
| 228 | |
|---|
| 229 | Some examples of common methods that the wrapper includes are: |
|---|
| 230 | |
|---|
| 231 | login(username, password): |
|---|
| 232 | This method wraps all the steps needed to log a user and go to the home |
|---|
| 233 | page to start a test. |
|---|
| 234 | |
|---|
| 235 | validate_breadcrumbs(*args): |
|---|
| 236 | This method receives multiple strings as parameters and validates that they |
|---|
| 237 | are included in the breadcrumbs. Notice that the last string received should |
|---|
| 238 | be the page where the test is located at that moment. |
|---|
| 239 | |
|---|
| 240 | To see the methods included in the wrapper please read the source code, it is |
|---|
| 241 | located on *enpraxis.educommons/enpraxis/educommons/tests/seleniumtests/seleniumWrapper.py* |
|---|