Test Driven Web Applications with FitNesse


Test Driven Web Applications with FitNesse

Elliotte Rusty Harold

Software Development Best Practices 2006

Thursday, September 14, 2006

elharo@metalab.unc.edu

http://www.cafeaulait.org/


Test Driven Development

  1. Write a test for a feature

  2. Code the simplest thing that can possibly work

  3. Run the test

  4. Test passed ? goto 1 : goto 2


Test Driven Development


Benefits of Test Driven Development are Well Known


Framework Limitations


Enter FitNesse


Acceptance Testing vs. Unit Testing


Demo Installing FitNesse

  1. Download the latest binary zip file (20060719 at the time of this writing) from http://fitnesse.org/FitNesse.DownLoad

  2. Unzip fitnesse20060719.zip to create a folder named "fitnesse"

  3. Run run.sh (Unix) or run.bat (Windows) in the fitnesse folder. This launches a web server on port 80:

           FitNesse (20060719) Started...
            port:              80
            root page:         fitnesse.wiki.FileSystemPage at ./FitNesseRoot
            logger:            none
            authenticator:     fitnesse.authentication.PromiscuousAuthenticator
            html page factory: fitnesse.html.HtmlPageFactory
            page version expiration set to 14 days.

  4. Point your browser at http://localhost


Install Problems


Live Demo!


Possible Results


The FitNesse Architecture


The Fixture is where the Magic Is

// Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the GNU General Public License version 2 or later.
package eg;

import fit.ColumnFixture;

public class Division extends ColumnFixture
{
  public double numerator;
  public double denominator;
  public double quotient() {
    return numerator/denominator;
  }
}

Compare to the Wiki markup

|eg.Division|
|numerator|denominator|quotient?|
|10       |2          |5        |
|12.6     |3          |4.2      |
|100      |4          |24       |

Don't read too much into this


A (Marginally) More Realistic Example

http://localhost:8080/FitNesse.FixtureCode

Types


Why the Indirection?


Setting the Classpath

!path *.jar
!path lib/*.jar
!path classes
!path lib

Importing spreadsheets


Table Fixture Styles


HTMLFixture


A simple web application


Creating a new page


Identifying tests


Test that the Page has a Title

This page is the first test of the online Petition

Let's test that the page has a title:

!path fitnesse.jar
!path htmlunit-1.5/lib/*.jar
!path htmlfixture20050422.jar

!|com.jbergin.HtmlFixture|
|http://www.cafeconleche.org/petition.phtml|
|Element Focus|t1|title|

Initial Result

You want the test to fail first:


Fix the problem


It still fails


Now the test passes!


Test that the Page has a Title and that the title is "Petition"

This page is the first test of the online Petition

Let's test that the page has a title:

!path fitnesse.jar
!path htmlunit-1.5/lib/*.jar
!path htmlfixture20050422.jar

!|com.jbergin.HtmlFixture|
|http://www.cafeconleche.org/petition.phtml|
|Element Focus|title|title|
|Text|Petition|

The general structure of an HTMLFixture test table

com.jbergin.HtmlFixture
URL
Instruction Name Instruction arguments
Instruction Name Instruction arguments
Instruction Name Instruction arguments
...

HTMLFixture Instructions


Addressing


Test that the character set is UTF-8

i.e. test that this element is present:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" id="charset">

The Table

!|com.jbergin.HtmlFixture|
|http://www.cafeconleche.org/demo/petition.phtml|
|Element Focus|charset|meta|
|Attribute|content|text/html; charset=utf-8|
|Attribute|http-equiv|content-type|

Breaking this Down

  1. Set the classpath

  2. Load the HTMLFixture

  3. Load the URL for the page we're testing.

  4. Find the element whose ID is charset and assert that its name is meta.

  5. Assert that this element has an attribute with the name content whose value is "text/html; charset=utf-8"

  6. Assert that this element also has an attribute with the name http-equiv whose value is "content-type"


Can combine multiple tests in one table

!|com.jbergin.HtmlFixture|
|http://www.cafeconleche.org/demo/petition.phtml|
|Element Focus|title|title|
|Text|Petition|
|Element Focus|charset|meta|
|Attribute|content|text/html; charset=utf-8|
|Attribute|http-equiv|content-type|

Use whitespace to line columns up if you like

!|com.jbergin.HtmlFixture|
|http://www.cafeconleche.org/demo/petition.phtml|
|Element Focus|title     |title|
|Text         |Petition  |
|Element Focus|charset   |meta|
|Attribute    |content   |text/html; charset=utf-8|
|Attribute    |http-equiv|content-type|

Annoyingly you can't just put in a blank line or a blank row to separate tests


Test that the petition data is included.

!|com.jbergin.HtmlFixture|
|http://www.cafeconleche.org/demo/petition.phtml|
|Element Focus|body     |body|
|Has Text     |Mickey Mouse|

Text Tests

!|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|

Text Tests Do cross tag boundaries

|Has Text |Mickey Mouse|

will find

<p>Mickey <em>Mouse</em></p>

Regular expressions

Java

Negative tests

!|com.jbergin.HtmlFixture|
|http://www.cafeconleche.org/demo/petition.phtml|
|Element Focus|body     |body|
|Fail|Has Text|Tom Delay|

Operators


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|

Verify you're at the Top-10 in Google


Watch out for cross-site scripting


JavaScript Tests

  1. Focus on a script element

  2. Then Execute onClick/onLoad/onChange/onClick/onFocus/onLoad/onMouseOver/onSelect/onSubmit/onUnload/etc.

!|com.jbergin.HtmlFixture|
|http://www.cafeconleche.org/demo/petition.phtml|
|Element Focus|loadhandler|script|
|Execute |onLoad|

Setting Page Properties


SubWikis


Standard Headers and Footers


Suites


SetUp and TearDown


More WIKI markup


WIKI Features


Other Languages


RowFixture


ActionFixture


A Final Thought


To Learn More


Index | Cafe con Leche

Copyright 2006 Elliotte Rusty Harold
elharo@metalab.unc.edu
Last Modified September 6, 2006