Web testing with Fitnesse Alessandro Marchetto Fondazione Bruno Kessler-IRST, Centro per la Ricerca Scientifica e Tecnologica Web testing using Fitnesse http://fitnesse.org/UsefulFixtures Three kind of web-fixtures can be used: 1. HtmlFixture: based on HtmlUnit http://fitnesse.org/FitNesse.HtmlFixture http://htmlunit.sourceforge.net Improved HtmlFixture: based on the HtmlFixture http://htmlfixtureim.sourceforge.net/ http://htmlfixtureim.sourceforge.net/documentation.shtml 2. WebFixture: based on HtmlUnit https://opensvn.csie.org/traccgi/webfixture/trac.cgi/wiki http://htmlunit.sourceforge.net 3. JWebFixture: based on JWebUnit http://jwebunit.sourceforge.net/index.html XUnit Web tools (1) HtmlUnit, HTTPUnit, JWebUnit, etc. - They are inspired by JUnit - They let us to verify the functionalities of Web sites - They emulate the relevant portions of browser behavior form submission, JavaScript, http authentication, cookies, automatic page redirection, etc. - They allow Java test code to examine returned pages in terms of text, DOM, or containers of forms, tables, and links - They make it easy to write Junit tests that verify HTTP requests and responses XUnit Web tools (2) Example import junit.framework.TestCase; import com.meterware.httpunit.WebResponse; import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebForm; import com.meterware.httpunit.WebRequest; public class SearchExample extends TestCase { Set the google page public void testSearch() throws Exception { WebConversation wc = new WebConversation(); WebResponse resp = wc.getResponse("http://www.google.com"); WebForm form = resp.getForms()[0]; Fill the google form form.setParameter("q", "HttpUnit"); WebRequest req = form.getRequest("btnG"); Send the request resp = wc.getResponse(req); get the google response assertNotNull(resp.getLinkWith("HttpUnit")); resp = resp.getLinkWith("HttpUnit").click(); assertEquals(resp.getTitle(), "HttpUnit"); assertNotNull(resp.getLinkWith("User's Manual")); verify the response } } HtmlFixture http://fitnesse.org/FitNesse.HtmlFixture - It is used to exercise and test web pages. - It allows us make assertions about the structure of a page and to navigate between pages. - We can also fire java script, submit forms, "click" links, etc. - It is based on a fixture that lets us navigate to any element of the page DOM. To use this we need some knowledge about the DOM (Document Object Model). HtmlFixture, the improved version - It is an improved version of the original one. - It is compatible with the original version but the implementation is a little bit changed. In fact, some advanced behaviors have been added and some minor problems of the original version are now correct. In that tutorial the original version is described and the differences with the improved version are only introduced. Installation and Setup (without Eclipse) Download the following packages: Fitnesse: http://fitnesse.org/FitNesse.DownLoad the zip file with the full distribution HtmlFixture: http://fitnesse.org/files/joeBergin/htmlfixture20050422.jar the jar library Htmlunit can be found at http://htmlunit.sourceforge.net/ section download select version 1.5 (old version) the zip file contains about 19 jar files Installation Steps 1.Unzip fitnesse.zip It creates the fitnesse directory with the following files and folders: FitNesseRoot, README.txt, dotnet, license.txt, fitnesse.jar, run.bat, run.sh 2.Create a sub-directory /lib in the fitnesse directory 3.Put all *.jar in the /lib htmlfixture*.jar htmlunit/*.jar 4.Go to the root/fitnesse folder and double-click run.bat It starts the Fitnesse server 5.Start up a browser and go to http://localhost/ It opens the Fitnesse wiki 6.Write a ProofOfTest page as follows: !path fitnesse.jar !path *.jar !path lib/*.jar !path classes !path lib | !- com.jbergin.HtmlFixture -! | | http://www.google.com | homePage | | Elements | >=2 | 7.Check “Test” in the properties page 8.Click the Test button 9.Check the results ... It will be: Installation and Setup (with the Eclipse plugin) 1. In Eclipse Use http://www.bandxi.com/fitnesse/download.html to install the Fitnesse plugin 2. Download the HtmlFixture and put it in the desktop - from http://selab.fbk.eu/marchetto/software/fitnesseImproved.zip (it is a local complete version of the Fitnesse framework enriched by the improved HtmlFixture) - from the original web site (it needs to be completed with a version of the original Fitnesse e with the required jars 3. Unzip it, in the desktop 4. In Eclipse - start a new (Tomcat) project - start Fitnesse for that project (into a project-dir) - write test cases in the Fitnesse-wiki !! set the path to the HtmlFixture dir in the desktop HtmlFixture table... general structure !path fitnesse.jar !path *.jar !path lib/*.jar !path classes !path lib Set of needed libraries | !- com.jbergin.HtmlFixture -! | | http://www.google.com | homePage | | Elements | >=2 | HTMLFixture URL or the name of an "element" defined earlier list of ordered commands (key sensitive) Commands Element Focus: test or retrieve a given element and make this element the focus of following instructions Element: test or retrieve a given element Elements: test or retrieve the number of child elements Types: assert or retrieve the number of descendants with the specified element name Type: like Element but depth first instead of breadth first Type Focus: like Element Focus but depth first instead of breadth first Attribute: test or retrieve a given attribute Focus: set the context for the following commands Focus Relative: set the context for the following commands relative to the current focus Text: assert the exact equality of the text of the current element Has Text: assert the substring equality of the text of the current element Matches Text: assert the regular expression equality of the text of the current element Execute: assert a script Set Value: "type" text into a form element Submit: follow a link or submit a form Click: synonym for Submit Save: assign the current focus to a named variable for later reference Preserve: do not clear variables when submitting Clear: unbind all variables Nodes: assert or retrieve the number of child nodes (as opposed to elements) of the focused element Node: assert or retrieve the type of the specified node Fail: boolean not; i.e. reverse the sense of a test see http://fitnesse.org/FitNesse.HtmlFixture for the complete list Elements: | !- com.jbergin.HtmlFixture -! | | http://www.google.com | homePage | | Elements | >=2 | Parameters: (1) java-like comparison operators (<, <=, >, >=, ==, !=). If no operator is given, equals (==) is assumed Assert that the number of child elements (of the current element) is as specified or query the number of elements if blank. See http://www.w3.org/TR/html4/index/elements.html for the list of HTML elements Element: |!-com.jbergin.HtmlFixture -!| | http://www.cafeconleche.org/petition.phtml | | Element | t1 | title| Parameters: (1) the relative number of the element or its id or name as specified by tag (2) the tag type (opt) (3) a name for the cell to be used in the second row of other tables or commands Assert that the specified child element has a given tag and give it a name, or query the tag and give it a name. Focus: | !- com.jbergin.HtmlFixture -! | | homePage | | Element | 2 | body | page Body | | Focus | pageBody | parameter: (1) name/url of an element that is to become the focus of assertions Focus row will refer to the body of the page. Focus Relative | !- com.jbergin.HtmlFixture -! | http://www.csis.pace.edu/~bergin | | Save | berginHome | | Focus Relative | xp | xpPage | | Has Text | Sorry. | will retrieve http://www.csis.pace.edu/~bergin/xp/ Parameters: (1) A part of a URL that will extend the page of the current focus. It will be retrieved and it will become the new focus. (2) An name for the cell (opt) Element Focus | !- com.jbergin.HtmlFixture -! | | http://www.csis.pace.edu/~bergin | | Element Focus | body | page Body | Its parameters are exactly those of Element and it behaves the same way except that it also sets this element to be the focus of subsequent rows. The current element is saved in the hash map with the given name Save | !- com.jbergin.HtmlFixture -! | http://www.csis.pace.edu/~bergin | | Save | berginHome | Parameters: (1) the name to give the current element The current element is saved in the hash map with the given name Text | !- com.jbergin.HtmlFixture -! | | http://www.cafeconleche.org/petition.phtml | | Element Focus | title | title | | Text | Petition | Parameters: (1) The text in the element (example: title element) (opt) Assert that the text in the element has the given text, or query for the text. Requires an exact match Has Text | !- com.jbergin.HtmlFixture -! | | http://www.cafeconleche.org/demo/petition.phtml | |Element Focus | body | body| | Has Text | Mickey Mouse | Parameters: (1) Any substring of the expected text of the element. (opt) Assert that the parameter is a substring of the actual text. Note that: |Has Text |Mickey Mouse| will find <p>Mickey <em>Mouse</em></p> Matches Text | !- com.jbergin.HtmlFixture -! | | http://www.cafeconleche.org/demo/petition.phtml | | Element Focus | body | body| | Has Text | Mickey Mouse | | Text | Mickey Mouse | | Matches Text | M.* Mouse | Parameters: (1) A regular expression intended to be matched by the text in the element. Assert that the regular expression is matched by the actual text. Attribute | !- com.jbergin.HtmlFixture -! | | http://csis.pace.edu/~bergin/patterns | | Type Focus | frame | 2 | | Attribute | src | select.html | select | | Focus Relative | symbol | select | Parameters: (1) name of the attribute (2) value of the attribute (opt) (3) an optional symbolic name for the value of the attribute Assert that the element has an attribute with the given name and value or assert that there is an attribute with the name and query for its value. Execute |!-com.jbergin.HtmlFixture-!| | http://www.cafeconleche.org/demo/petition.phtml | | Element Focus | loadhandler | script | | Execute | onLoad | Parameters: (1) a condition on which to run this java script element. e.g. onClick. Fire the condition if it is defined for this script element. Note that the underlying htmlUnit still has only partial support for javascript. Set Value |!-com.jbergin.HtmlFixture!-| | http://www.cafeconleche.org/demo/petition.phtml | | Element Focus | name | input | | Set Value|John Doe | Parameters: (1) Text to be entered into this (input, textarea, or select) element. For a submit the text is used to set the selected attribute of the element. For the others the text is entered. You can "check" a checkbox using Set Value to checked. If you set it to an empty string it will be unchecked. Submit |!-com.jbergin.HtmlFixture!-| | http://www.cafeconleche.org/demo/petition.phtml | | Element Focus | name | input | | Set Value|John Doe | | Element Focus | email | input | | Set Value | jdoe@example.com | | Element Focus | s1 | | Submit | namePage | Parameters: (1) The name of the page returned. Click this link or submit this form and capture the resulting page. Click It is a synonym for Submit. Indeed, it works exactly the same Types |!-com.jbergin.HtmlFixture-!| | http://www.google.com | | Types | h2 | | …it will return 0 | Types | input | | …it will return 7 Parameters: (1) A valid type (tag) name (e.g. table or a) (2) An integer: the asserted number of descendants of the given type (opt) Assert that the current element has a certain number of descendant elements of the given type. If the third column is blank it will query for the number of descendants of that type. Type | !- com.jbergin.HtmlFixture -! | | http://www.cafeconleche.org/demo/petition.phtml | | Type | p | 3 | third | | Type | table |3 | filler | | Focus | third | | Matches Text | laborers.$ | Parameters: (1) A valid type (tag) name (e.g. table or a) (2) An integer index (3) A name for the resulting element (opt) Assert that there are at least "index" descendant elements with the given type. Give the name to the one at "index". If the third parameter is blank, no name will be given to the resulting element. Type Focus: Exactly like Type but it also sets the current focus. Nodes parameters: (1) the number of child nodes of this item (opt) Assert that the item has the specified number of children or query for the number if blank. Note that this one counts all nodes, not just Element nodes. Node parameters (1) the node index relative to the beginning (one based) (2) the node (type) name (e.g head,.#text ,...) (opt) Assert that the specified node has the given type. Or query for the type if blank. Note: HTML elements are nodes, attributes are nodes, text is a node Blank Token | !- com.jbergin.HtmlFixture -! | | http://csis.pace.edu/~bergin/hello.html| | Type Focus | title | 1 | titleText | | Text | $blank$ | Asserts that the titleText is blank (empty) Using the Blank Token command, we can specify that an element should consist of blank text. The default token is “$blank$”. Symbol | !- com.jbergin.HtmlFixture -! | | http://www.cafeconleche.org/demo/petition.phtml | | Symbol | big | > 10 | | Elements | symbol big | Parameters: (1) name for a new symbol (2) string value of the symbol You can use this command to give symbolic names to strings you want to appear in other cells of your tests. This gives a name and a value to your symbol which may then be used later. List | !- com.jbergin.HtmlFixture -! | | http://www.cafeconleche.org/demo/petition.phtml | | List |values | Charlemagne | Gandhi | Sun Tsu | | Type Focus | title | 1 | | Has Text | symbol values[2] | Parameters: (1) A name for the list (2...n) values to be stored in the list. Any string values. A List is a symbol with a given name but many values. The values in the symbol can be obtained by indexing from one. Fail |!-com.jbergin.HtmlFixture-!| | http://www.cafeconleche.org/demo/petition.phtml | | Element Focus | body | body| | Fail | Has Text| Tom Delay | ... Assert that "Tom Delay" has not signed the petition |!-com.jbergin.HtmlFixture-!| | Fail | Elements | 3 | … Assert that the number of elements is NOT 3. The fail command is a modifier for many other commands. You use it by putting Fail in a cell alone, before any other command (some ignore it). The intent is to reverse the sense of the test. Note (1): | !- com.jbergin.HtmlFixture -! | We use this is equivalent to !|com.jbergin.HtmlFixture| and to | HtmlFixture | Note (2): It is possible to set some referecens among table, such as: HtmlFixture http://csis.pace.edu/~bergin/gandhi.html Save homePage HtmlFixture homePage Element Focus definition use 2 body pageBody HtmlFixture, the improved version See http://htmlfixtureim.sourceforge.net/documentation.shtml for the complete list of commands provided by the improved version. Some of those commands are: Print Dom: Prints types and attributes of the DOM starting at the current element in an html table Print Cookies: Prints a list of cookies in the web client in table format Cookie: Asserts that the web client has a cookie of by the specified name Timeout: Sets the timeout for the simulated web browser Sleep: Causes the webClient's thread to sleep for specified interval. This allows for use with asyncronous Ajax to allow for the child thread to complete Click Confirm: Does the same as Click and then clicks OK on any javascript confirm dialog that appears Print Dom | !- com.jbergin.HtmlFixture -! | | http://www.cafeconleche.org/demo/petition.phtml | | Print Dom | | Parameters: (1) empty cell for the results Prints types and attributes of the DOM starting at the current element in an html table. This command is useful for displaying information while writing tests on an existing system or prototype. Print Cookies parameters (1) empty cell for the results Prints a list of cookies in the web client in table format. ..see the example… * set up web client | HtmlFixture| http://localhost | | Javascript | on | | Preserve | on | * load the cookie test page * click the button (sets a cookie --- name=favorite_cookie; value=snickerdoodle -- and displays it in an alert box) * display javascript message to verify the javascript ran ok print the cookie | HtmlFixture | | http://localhost/HtmlFixtureDemo.SetCookieTestPage | | Element Focus | set_cookies | input | | Click | cookiePage | | Javascript Message | | Print Cookies | Cookie paramters (1) cookie name (required) (1) cookie value (optional) Asserts that the web client has a cookie of by the specified name. If a value is supplied, asserts that the value of the cookie is as specified. If value is blank, the value of the cookie will be displayed in the blank cell on test. ..see the example… * go to the cookie page from before * assert there is a cookie with name=favorite_cookie (pass) * assert there is a cookie with name=favorite_cookie and display the value (pass) * assert the cookie value is snickerdoodle (pass) * assert the cookie value is chocolate chip (fail) | HtmlFixture | | cookiePage | | Cookie | favorite_cookie | | Cookie | favorite_cookie | snickerdoodle | | Cookie | favorite_cookie | chocolate chip | | Fail | Cookie | favorite_cookie | | Fail | Cookie | favorite_cookie | snickerdoodle | | Fail | Cookie | favorite_cookie| chocolate chip | Timeout paramters (1) time in milliseconds ets the timeout for the simulated web browser. When loading a page, the browser will wait this amount of time twice - once to set up the connection and once more to get the page. Setting timeout to 0 causes the browser to wait indefinitely. NOTE: This command also reinitializes the browser. In particular, cookies are reset. ...see the example… * Sets the timeout to 1 millisecond and requests home page - this will produce Timeout exception exception. Sets infinite timeout and gets the page, sets timeout of 10 seconds and gets the page. | HtmlFixture | | joeBody | | Timeout | 1 | | Focus | http://www.musiciansfriend.com | | Timeout | 0 | | Focus http://www.musiciansfriend.com | | Timeout | 10000 | | Focus | http://www.musiciansfriend.com | Sleep Parameters (1) time in milliseconds Causes the client’s thread to sleep for specified interval. This allows for use with asyncronous Ajax to allow for the child thread to complete. NOTE: Ajax is available in development version >06-2006 of htmlunit. Sample 1 • The sample page – http://www.cafeconleche.org/demo/petition.phtml ...In browser... ...HTML code... <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta id="charset" http-equiv="content-type" content="text/html; charset=utf-8" /> <title id="t1">Petition</title> </head> <body id="body"> <h1 id="h1">Petition</h1> <p>We the undersigned request that Congress declare February 30th to be National Political Integrity day, to provide due recognition of the valuable service done for this country by all its honest politicians. </p> Mickey Mouse<br /> Donald Duck<br /> Goofy<br /> <h2>Add Your Signature:</h2> <form action="sign.phtml" id="sigform"> Name: <input name="name" size="64" id="name"/><br /> Email: <input name="email" size="64" id="email"/><br /> <input type="submit" id="s1"/> </form> </body> </html> Sample - Test signing the petition |!-com.jbergin.HtmlFixture!-| | http://www.cafeconleche.org/demo/petition.phtml | | Element Focus | name | input | | Set Value | John Doe | | Element Focus | email | input | | Set Value | jdoe@example.com | | Element Focus | s1 | | Submit | | Element Focus | body | body | | Has Text | John Doe | Sample 2 • The google seach – Get the page at http://www.google.com – Put the string “IRST” in the input field – Click the submit button – Verify it the returned page contains the string “www.itc.it/irst/ ” Wrong table !path fitnesse.jar !path *.jar !path lib/*.jar !path classes !path lib |!-com.jbergin.HtmlFixture-!| | http://www.google.com | | Element Focus | q | input | | Set Value | IRST | | Element Focus | btnI | button| | Submit | | Has Text | www.itc.it/irst | Where we search this element? It is possible to find this? Get/Post ? Right table !path fitnesse.jar !path *.jar !path lib/*.jar !path classes !path lib |!-com.jbergin.HtmlFixture-!| | http://www.google.com | requestPage| | Focus | requestPage | | Element Focus | q | input | textField | | Set Value | IRST | | Focus | requestPage | | Element Focus | f | form | | Submit | search | | Has Text | www.itc.it/irst | Sample 3 • The google seach – Get the page at http://www.google.com – Put “IRST” in the text field – Click submit – Analiyze the page in order to verify if the web site http://www.itc.it/irst/ is in the first positition of the Top-10 !path fitnesse.jar !path *.jar !path lib/*.jar !path classes !path lib |!-com.jbergin.HtmlFixture-!| | http://www.google.com | requestPage| | Focus | requestPage | | Element Focus | q | input | textField | | Set Value | IRST | | Focus | requestPage | | Element Focus | f | form | | Submit | search | | Types | input | | | Focus | search | |Type Focus | h2 | 1 | resp | |Attribute| class | r| |Type Focus | a| 1 | linkRef | |Attribute| href | http://www.itc.it/irst/ | !path fitnesse.jar !path *.jar !path lib/*.jar !path classes !path lib |!-com.jbergin.HtmlFixture-!| | http://www.google.com | requestPage| | Focus | requestPage | | Element Focus | q | input | textField | | Set Value | IRST | | Focus | requestPage | | Element Focus | f | form | | Submit | search | | Types | input | | | Focus | search | What happens if it =3? |Type Focus | h2 | 1 | resp | |Attribute| class | r| |Type Focus | a| 1 | linkRef | |Attribute| href | http://www.itc.it/irst/ | Sample 4 • The online FORM sample – The page http://www.w3schools.com/html/html_forms.asp contains several information about HTML – Moreover, it contains a section titled: • The Form's Action Attribute and the Submit Button – This last section contains a GET form.... – Fill this form (with a sentence) – Click its submit button – Verify that the response contains the written sentence ...The form that we want to analyze.... ...the output.... !path fitnesse.jar !path *.jar !path lib/*.jar !path classes !path lib |!-com.jbergin.HtmlFixture-!| | http://www.w3schools.com/html/html_forms.asp | requestPage | | Focus | requestPage | | Element Focus | user | input | textField | | Set Value | sentence | | Focus | requestPage | | Element Focus | input |form | | Submit | | | Has Text | user=sentence |