QA/Execution/Web Testing/Selenium Python: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
No edit summary
 
(35 intermediate revisions by the same user not shown)
Line 1: Line 1:
Python org's [http://www.python.org/download/ download].<br>The Selenium org's documentation on [http://seleniumhq.org/docs/appendix_installing_python_driver_client.html#configuring-selenium-rc-python-reference configuring Selenium RC for Python].  
*Python org's [http://www.python.org/download/ download].  
*The Selenium org's documentation on [http://seleniumhq.org/docs/appendix_installing_python_driver_client.html#configuring-selenium-rc-python-reference configuring Selenium RC for Python].
*Selenium RC requires Java.&nbsp; Download page [http://java.com/en/download/ here].


These notes are based on Selenium RC 1.0.1  
These notes are based on Selenium RC 1.0.1  
Line 10: Line 12:


#Open the .htm script in Selenium IDE.<br>  
#Open the .htm script in Selenium IDE.<br>  
#Select File &gt; Export Test Case As &gt; Python - Selenium RC. Naming with a .py file extension associates the file with Python.&nbsp; Because the script has classes based on the Python script file name, the file name should be limited to "class name safe" characters such as letters, numbers and underscores.<br>  
#Select File &gt; Export Test Case As &gt; Python - Selenium RC. A .py file extension associates the file with Python.&nbsp; Because the exporter creates class names based on the Python script file name, the file name should be limited to "safe" characters such as letters, numbers and underscores. A dash will create an invalid class name, as will other 'operator' characters. <br>  
#Edit the Python script as needed in Python IDLE&nbsp;or a text editor.<br>
#Edit the Python script as needed in Python IDLE&nbsp;or a text editor.<br>
<blockquote>
<blockquote>
*The '''setUp def''' may require changes to parameters in ''self.selenium = selenium( )'', which launches the browser. The 3rd parameter is the browser to launch. The 4th parameter is the base URL when starting the script. For more information see Selenium's [http://seleniumhq.org/docs/05_selenium_rc.html#learning-the-api Learning the API].<br>  
*The '''setUp def''' may require changes to parameters in ''self.selenium = selenium( )'', which is the call that launches the browser. The 3rd parameter is the browser type. The 4th parameter is the base URL when starting the script. For more information see the Selenium RC doc [http://seleniumhq.org/docs/05_selenium_rc.html#starting-the-browser Starting the Browser].<br>  
*'''While, WhileEnd, Goto, GotoIf''' and other commands that are not Selenium built-ins are converted as a call to the "sel" class and marked as a comment. The commands can be found by searching for <span style="font-style: italic;">"</span>''# sel.''"<br>
*Comments on how specific IDE commands are converted to Python can be found below.
*Reminders regarding While loops - Syntax is "''while &lt;conditional&gt;:''". Statements in the while block are indented. No explicit end-while statment. End of code blocks indicated by a descreased indention.<br>
</blockquote>
*'''GotoIf and Goto''' commands in IDE were perhaps substituting for a high-level language control flow, which Python is likely has a command for.<br>
==== Method B - Build a Python script from scratch. ====
*'''Review sel.get_eval( ) calls'''. The IDE exporter converts the 1st parameter of an storeEval, store or storeExpression command to a string for get_eval(&nbsp;).&nbsp; Although get_eval will still execute the string as JavaScript, it may not create the same results as in IDE.&nbsp; For example, ''storedVars['myVar']'' will not reference the variable ''myVar''.&nbsp; The JavaScript should generally be rewritten in Python.<br>
 
*'''Review print( ) calls'''. Although the IDE exporter seperates literal text from variables names, the '+' operator may not always be desired. <br>
The [http://docs.python.org/library/unittest.html Python unit testing framework] is the foundation of the tests.  
</blockquote>
 
*The Python documentation has a [http://docs.python.org/library/unittest.html#basic-example basic example] that demonstrates its usage.
 
*Selenium org's RC documentation has an example of a [http://seleniumhq.org/docs/05_selenium_rc.html#python Python script], which is the same structure created by the IDE exporter to Python.
 
The Python unit testing framework is separate from the Selenium class which interacts with the browser.  
 
*The Python code [http://seleniumhq.org/docs/05_selenium_rc.html#starting-the-browser here] are the commands that create the selenium instance and start the browser.
 
*The Python Selenium class documentation is on the client in the RC directory at selenium-remote-control-1.0.1\selenium-python-client-driver-1.0.1\doc\index.html. Generally every Selenium IDE command has similarly named command in Python, although there are exceptions as noted in the next point.
 
*The Selenium IDE can generate Python code for individual SIDE commands by exporting a "script" to Python that contains only one or a few commands. The exporter does not require a fully operational script. An single SIDE command may be translated to one or more Python functions. For example, the verifyXYZ IDE commands are generally translated to a get_xyz( ) passed to an assertion function.


==== Method B - Build a Python script from scratch. ====
==== Shared Libraries ====


*The Selenium org documentation has an example [http://seleniumhq.org/docs/05_selenium_rc.html#python here]. It uses the same structure as what's created by the IDE exporter and contains a few comments.
[[Code libraries for AMO pages]] are available to help centralize code and simplify python scripts. &nbsp;They contain functions that execute features and locators for page elements.<br>  
*The Python Unit Testing Framework is described [http://docs.python.org/library/unittest.html here]. <br>  
*The method that launches the browser is described [http://seleniumhq.org/docs/05_selenium_rc.html#learning-the-api here].
*The Python selenium class documentation is in the client RC directory at selenium-remote-control-1.0.1/selenium-python-client-driver-1.0.1/doc/index.html


<br>  
<br>


=== Settting Up Selenium RC  ===
=== Setting Up Selenium RC  ===


#Download the Selenium RC zip file from the Selenium org RC downloads page. Unzip to a convenient location.  
#Download the Selenium RC zip file from the Selenium org [http://seleniumhq.org/download/ downloads] page. Unzip to a convenient location.  
#In the selenium-remote-control-1.0.1\selenium-python-client-driver-1.0.1 directory find the file selenium.py.  
#In the selenium-remote-control-1.0.1\selenium-python-client-driver-1.0.1 directory find the file selenium.py.  
#Copy selenium.py to the Python installation's \Lib directory. For a default Python 2.6 installation this would be c:\Python26\Lib.
#Copy selenium.py to the Python installation's \Lib directory. For a default Python 2.6 installation this would be c:\Python26\Lib.


=== <br> Starting the RC server  ===
<br>
 
=== Starting the RC server  ===


==== In Windows  ====
==== In Windows  ====


#Open a command window and change directories to selenium-remote-control-1.0.1/selenium-server-1.0.1 directory. It should contain selenium-server.jar.  
#Open a command window and change directories to selenium-remote-control-1.0.1/selenium-server-1.0.1 directory. It should contain selenium-server.jar.  
#Enter the command "java -jar selenium-server.jar"
#From the command prompt enter ''java -jar selenium-server.jar''


If the server is running correctly it will print a few lines and *not* return to the command line prompt. Whenever a script with Selenium runs the server window will display a few more lines and continue waiting.  
If the server is running correctly it will print a few lines and ''not'' return to the command line prompt. When a script with Selenium runs the server window will display a few more lines and return to waiting.  


<br>  
<br>  
Line 50: Line 62:


==== In Windows  ====
==== In Windows  ====
===== Using Python IDLE<br>  =====


#Launch Python IDLE, which creates a Python Shell window.  
#Launch Python IDLE, which creates a Python Shell window.  
#From the menu select File &gt; Open and select the script from the file browser.&nbsp; This is expected to open another window containing the script.  
#From the menu select File &gt; Open and select the script from the file browser.&nbsp; The script appears in another window.  
#From the script window select Run &gt; Run Module. Results of the run will appear in the Python Shell window.
#Check code syntax by selecting Run &gt; Check Module.
#Run the script by selecting Run &gt; Run Module. Results appear in the Python Shell window.<br>
 
===== From command window<br>  =====
 
*Note:&nbsp;The Python installer does not change the ''path'' environment variable which allows the python to run from anywhere.&nbsp; Update from Start &gt;&nbsp;Control Panel &gt;&nbsp;System &gt; Advanced tab &gt;&nbsp;Environment Variables button.&nbsp; From the System Variables list highlight ''path'' and select Edit.&nbsp; Add your Python installation directory, for example c:\Python26 for the default installation, remembering to include semi-colon (&nbsp;; ) between it and the existing list.&nbsp; Select OK&nbsp;in the dialogs to save. &nbsp;Value applies to new command windows.<br>
*To run a script enter<br>
<blockquote>python ''myscript''<br> where ''myscript'' is the script file.&nbsp; More info on Python command line options [http://docs.python.org/using/cmdline.html here].<br> </blockquote>
*To start a script in the debugger enter<br>
<blockquote>python -m pdb ''myscript''<br> where ''myscript'' is the script file.&nbsp; More information about the debugger [http://docs.python.org/library/pdb.html here]. </blockquote>
<br>
 
=== Things we don't understand yet  ===
 
...and would like to know. (Well, the author doesn't know. Maybe someone else knows)


<br>Things we don't know yet.  
If someone has clues to the following mysteries, you are welcome to update the wiki page or contact Truman.  


(or, things the author doesn't know)
*What is the difference between running a script in IDLE and Python command window?
*In IDLE&nbsp;what causes the Callback traces at the end of an apparently successful run?<br>
<blockquote>'''Answer?''' Appears to be an issue with IDLE which is supposedly fixed in later versions.&nbsp; http://bugs.python.org/issue2821<br> </blockquote>
*In IDLE why does the prompt "Do you want to exit altogether?" appear?<br>


if you have some clues to the following mysteries, you are welcome to update the wiki page or contact Truman.
<br>


*What causes the Callback traces at the end of a successful run?
=== Comments on the SIDE script exporter for Python  ===
*How to re-direct the RC runtime log to a file.


<br>
*'''Indent the body of the script.&nbsp; '''A code block in Python is defined by indention rather than delimiters such as {&nbsp;}.&nbsp; While the exporter correctly indents the Python testing functions that drive the script, most of the converted IDE commands are not.&nbsp; Those statements need to be indented to the same level as the sel = self.selenium statement. &nbsp;Note that indention is in spaces and not tabs. Mixing them causes errors.
<blockquote>
*The Python IDLE&nbsp;editor has a simple block indention command:&nbsp;1)&nbsp;highlight the lines to indent, 2)&nbsp;select from the menu Format &gt;&nbsp;Indent Region.&nbsp; The Format menu also has Dedent, which is a reverse indent.
</blockquote> <blockquote>
*The VI editor can insert with spaces as follows: 1) in visual mode type capital V and highlight the lines to indent. 2) in command mode enter
<blockquote><pre>'&lt;,'&gt;s/^/        /</pre></blockquote> <blockquote>which inserts at the beginning of each highlighted line the spaces between the last two slashes.&nbsp; Identation within functions, while-loops, if-then statements, etc is normally 4 spaces.</blockquote></blockquote> <blockquote>
*The VI&nbsp;editor can be set to use 4 spaces in place of a tab with the following entered in command&nbsp; mode:
<blockquote><pre>set tabstop=4 expandtab shiftwidth=4 softtabstop=4
</pre></blockquote> <blockquote>(can someone explains what this means?)</blockquote></blockquote>
*'''while, whileEnd, goto, gotoIf, label''' and other commands that are not Selenium built-ins are converted as a call to the selenium instance and marked as a comment. They can be found by searching for "# sel." All comments that begin this way will likely need a Python equivalent.<br>
*'''gotoIf '''and '''goto''' commands in an IDE script were perhaps a substitute for a if-else statement or other high-level language control flow.
*'''Replace sel.get_eval( )''' with appropriate Python statements.&nbsp; The IDE exporter converts the 1st parameter of an storeEval, store or storeExpression command to a string for the Python get_eval( ) which executes the string as JavaScript. It may not create the same results as in IDE and generally will be simpler in Python anyway.&nbsp; In particular, ''storedVars['myVar']'' will not reference the variable ''myVar''.
*'''Review print( ) calls'''. Although the IDE exporter seperates literal text from variables names, the '+' operator may not always be desired.
*'''wait_for_page_to_load( )''' is given a string value.&nbsp; It makes sense for it to be a numeric value, perhaps a constant.
*'''verifyXYZ( ) IDE commands''' are generally converted to [http://docs.python.org/library/unittest.html?highlight=unittest#testcase-objects failUnless, failIf or assertEqual] functions that incorporate a get_XYZ function to retrieve the text, attribute, location, etc, and compare it to the pattern parameter in the IDE command.
<blockquote>
*the Python statement may not have the same verification functionality as the IDE command since the IDE pattern parameter is converted without parsing the prefix (ex: regexpi: ).&nbsp; The Python module for regular expressions is named [http://docs.python.org/library/re.html?highlight=regular%20expressions#module-contents re].
*changing the failXYZ calls to assertABC could make the script easier to read.
*element verification errors are reported by a ''try-except'' statement that surrounds each assert/fail call and appends an error message to a verificationErrors list.&nbsp; At the end of the script, in the tearDown function, the list is dumped and the Python traceback is called if the list is not null.
*TBD: other information to include in error message, such as element identifier/locator, regular expressions, expected and actual values, add-on/persona name, category.
*TBD: formating and printing the verification errors for post-runtime processing by the test execution framework.<br>
</blockquote>

Latest revision as of 22:54, 14 March 2010

These notes are based on Selenium RC 1.0.1

Creating a Selenium script in Python

Method A - Convert an Selenium IDE script to Python

Use for a full IDE script or, a script with a few commands as a shortcut to creating Python code with Selenium calls.

  1. Open the .htm script in Selenium IDE.
  2. Select File > Export Test Case As > Python - Selenium RC. A .py file extension associates the file with Python.  Because the exporter creates class names based on the Python script file name, the file name should be limited to "safe" characters such as letters, numbers and underscores. A dash will create an invalid class name, as will other 'operator' characters.
  3. Edit the Python script as needed in Python IDLE or a text editor.
  • The setUp def may require changes to parameters in self.selenium = selenium( ), which is the call that launches the browser. The 3rd parameter is the browser type. The 4th parameter is the base URL when starting the script. For more information see the Selenium RC doc Starting the Browser.
  • Comments on how specific IDE commands are converted to Python can be found below.

Method B - Build a Python script from scratch.

The Python unit testing framework is the foundation of the tests.

  • The Python documentation has a basic example that demonstrates its usage.
  • Selenium org's RC documentation has an example of a Python script, which is the same structure created by the IDE exporter to Python.

The Python unit testing framework is separate from the Selenium class which interacts with the browser.

  • The Python code here are the commands that create the selenium instance and start the browser.
  • The Python Selenium class documentation is on the client in the RC directory at selenium-remote-control-1.0.1\selenium-python-client-driver-1.0.1\doc\index.html. Generally every Selenium IDE command has similarly named command in Python, although there are exceptions as noted in the next point.
  • The Selenium IDE can generate Python code for individual SIDE commands by exporting a "script" to Python that contains only one or a few commands. The exporter does not require a fully operational script. An single SIDE command may be translated to one or more Python functions. For example, the verifyXYZ IDE commands are generally translated to a get_xyz( ) passed to an assertion function.

Shared Libraries

Code libraries for AMO pages are available to help centralize code and simplify python scripts.  They contain functions that execute features and locators for page elements.


Setting Up Selenium RC

  1. Download the Selenium RC zip file from the Selenium org downloads page. Unzip to a convenient location.
  2. In the selenium-remote-control-1.0.1\selenium-python-client-driver-1.0.1 directory find the file selenium.py.
  3. Copy selenium.py to the Python installation's \Lib directory. For a default Python 2.6 installation this would be c:\Python26\Lib.


Starting the RC server

In Windows

  1. Open a command window and change directories to selenium-remote-control-1.0.1/selenium-server-1.0.1 directory. It should contain selenium-server.jar.
  2. From the command prompt enter java -jar selenium-server.jar

If the server is running correctly it will print a few lines and not return to the command line prompt. When a script with Selenium runs the server window will display a few more lines and return to waiting.


Running the Selenium script in Python

In Windows

Using Python IDLE
  1. Launch Python IDLE, which creates a Python Shell window.
  2. From the menu select File > Open and select the script from the file browser.  The script appears in another window.
  3. Check code syntax by selecting Run > Check Module.
  4. Run the script by selecting Run > Run Module. Results appear in the Python Shell window.
From command window
  • Note: The Python installer does not change the path environment variable which allows the python to run from anywhere.  Update from Start > Control Panel > System > Advanced tab > Environment Variables button.  From the System Variables list highlight path and select Edit.  Add your Python installation directory, for example c:\Python26 for the default installation, remembering to include semi-colon ( ; ) between it and the existing list.  Select OK in the dialogs to save.  Value applies to new command windows.
  • To run a script enter

python myscript
where myscript is the script file.  More info on Python command line options here.

  • To start a script in the debugger enter

python -m pdb myscript
where myscript is the script file.  More information about the debugger here.


Things we don't understand yet

...and would like to know. (Well, the author doesn't know. Maybe someone else knows)

If someone has clues to the following mysteries, you are welcome to update the wiki page or contact Truman.

  • What is the difference between running a script in IDLE and Python command window?
  • In IDLE what causes the Callback traces at the end of an apparently successful run?

Answer? Appears to be an issue with IDLE which is supposedly fixed in later versions.  http://bugs.python.org/issue2821

  • In IDLE why does the prompt "Do you want to exit altogether?" appear?


Comments on the SIDE script exporter for Python

  • Indent the body of the script.  A code block in Python is defined by indention rather than delimiters such as { }.  While the exporter correctly indents the Python testing functions that drive the script, most of the converted IDE commands are not.  Those statements need to be indented to the same level as the sel = self.selenium statement.  Note that indention is in spaces and not tabs. Mixing them causes errors.
  • The Python IDLE editor has a simple block indention command: 1) highlight the lines to indent, 2) select from the menu Format > Indent Region.  The Format menu also has Dedent, which is a reverse indent.
  • The VI editor can insert with spaces as follows: 1) in visual mode type capital V and highlight the lines to indent. 2) in command mode enter
'<,'>s/^/        /

which inserts at the beginning of each highlighted line the spaces between the last two slashes.  Identation within functions, while-loops, if-then statements, etc is normally 4 spaces.

  • The VI editor can be set to use 4 spaces in place of a tab with the following entered in command  mode:
set tabstop=4 expandtab shiftwidth=4 softtabstop=4

(can someone explains what this means?)

  • while, whileEnd, goto, gotoIf, label and other commands that are not Selenium built-ins are converted as a call to the selenium instance and marked as a comment. They can be found by searching for "# sel." All comments that begin this way will likely need a Python equivalent.
  • gotoIf and goto commands in an IDE script were perhaps a substitute for a if-else statement or other high-level language control flow.
  • Replace sel.get_eval( ) with appropriate Python statements.  The IDE exporter converts the 1st parameter of an storeEval, store or storeExpression command to a string for the Python get_eval( ) which executes the string as JavaScript. It may not create the same results as in IDE and generally will be simpler in Python anyway.  In particular, storedVars['myVar'] will not reference the variable myVar.
  • Review print( ) calls. Although the IDE exporter seperates literal text from variables names, the '+' operator may not always be desired.
  • wait_for_page_to_load( ) is given a string value.  It makes sense for it to be a numeric value, perhaps a constant.
  • verifyXYZ( ) IDE commands are generally converted to failUnless, failIf or assertEqual functions that incorporate a get_XYZ function to retrieve the text, attribute, location, etc, and compare it to the pattern parameter in the IDE command.
  • the Python statement may not have the same verification functionality as the IDE command since the IDE pattern parameter is converted without parsing the prefix (ex: regexpi: ).  The Python module for regular expressions is named re.
  • changing the failXYZ calls to assertABC could make the script easier to read.
  • element verification errors are reported by a try-except statement that surrounds each assert/fail call and appends an error message to a verificationErrors list.  At the end of the script, in the tearDown function, the list is dumped and the Python traceback is called if the list is not null.
  • TBD: other information to include in error message, such as element identifier/locator, regular expressions, expected and actual values, add-on/persona name, category.
  • TBD: formating and printing the verification errors for post-runtime processing by the test execution framework.