FANDOM


Big thanks to http://schuchert.wikispaces.com/FitNesse.Tutorials

This page is for .NET testing only.

These instructions assume port 8080 is used for the web server. If the port is not available, change references to 8080 to something else.

InstallationEdit

You'll need Java installed on your computer. Get it from java.com and install as usual.

Download fitnesse.jar file (instructions on http://fitnesse.org), put it into the c:\fit folder and run the following command to install and run:

java -jar fitnesse.jar -p 8080

Shutting downEdit

Go to: http://localhost:8080/?shutdown

RunningEdit

The same command is used to run FitNesse, if it's not already running.

java -jar fitnesse.jar -p 8080

launch browser to http://localhost:8080

run.batEdit

You may want to create a run.bat file in the FitNesse folder that will start the web server and launch the web browser. Example:

@start java -jar fitnesse.jar -p 8080
@sleep .5
@start http://localhost:8080/

Invoking tests from a command lineEdit

java -jar fitnesse.jar -p 8079 -c "FitNesse.MyProject?test&format=text"

Installing .NET extensionsEdit

While FitNesse server is shutdown:

Sample TestsEdit

First .NET TestEdit

  • Create C:\myfolder\mytest.cs:
public class MyFixture {
     public System.String Now() {
	return "12:00";
     }
}
  • Compile it into a DLL using command:
csc /t:library mytest.cs
!define TEST_SYSTEM {slim}
!path c:\myfolder\mytest.dll
!define COMMAND_PATTERN {%m -r fitSharp.Slim.Service.Runner,"c:\program files\fitsharp\fitsharp.dll" %p}
!define TEST_RUNNER {c:\program files\fitsharp\Runner.exe}

!|MyFixture|
|Now?|
|12:00|
Assertions: 2 right, 0 wrong, 0 ignored, 0 exceptions
    • and "Tests Executed OK" in the top-right corner.

TroubleshootingEdit

  • If you get "Could not load file or assembly 'file:///C:\fit\classes'", Edit the FitNesse page http://localhost:8080/FitNesse?edit and delete or comment the following line, and then click Test again.
!path classes
  • If test "hangs" for a long time, change TEST_RUNNER variable to point to RunnerW.exe. When you click Test, the runner displays a Window and waits for you to hit Go before running the test. The window will then show an errors while the test is run. In addition, you can attach the runner to the debugger before pressing the initial Go.
  • You can also use System.Console.WriteLine to output information from your fixture, which will end up available via a link from the test page.

Second .NET TestEdit

  • Edit the C:\myfolder\mytest.cs file and add the following code:
namespace slim_example
{
  public class ShouldIBuyMilk
  {
    private int _cash;
    private int _pintsOfMilkRemaining;
    private string _useCreditCard;
 
    public void SetCashInWallet(int cash)
    {
      _cash = cash;
    }
 
    public void SetCreditCard(string useCreditCard)
    {
      _useCreditCard = useCreditCard;
    }
 
    public void SetPintsOfMilkRemaining(int pints)
    {
      _pintsOfMilkRemaining = pints;
    }
 
    public string GoToStore()
    {
      if (_cash > 0 || _useCreditCard.Equals("yes"))
        return "yes";
      return "no";
    }
  }
}
  • Compile it like before:
csc /t:library mytest.cs
|import|
|slim_example|
 
|Should I Buy Milk|
|cash in wallet|credit card|pints of milk remaining|go to store?|
|      0       |    no     |      0                |    no      |
|      10      |    no     |      0                |    yes     |
|      0       |    yes    |      0                |    yes     |
|      10      |    yes    |      0                |    yes     |
|      0       |    no     |      1                |    no      |

Additional methodsEdit

SLiM Decision tables support additional methods:

public void Execute()

Which is called once for each row, after setting all of the fields/attributes/properties (calling all of the setX methods).

public void Reset()

Which is called once for each row, after completely processing the entire row.

public List<object> Table(List<List<String>> table)

Which is called once for each table, before everything else. Using these methods, it's possible to use Decision Tables for a majority of tests.

Script TestEdit

  • Edit the C:\myfolder\mytest.cs file and add the following code:
public class LoginDialogDriver {
  private string userName;
  private string password;
  private string message;
  private int loginAttempts;

  public LoginDialogDriver(string userName, string password) {
    this.userName = userName;
    this.password = password;
  }
  public bool loginWithUsernameAndPassword(string userName, string password) {
	loginAttempts++;
	bool result = userName == this.userName && password == this.password;
	if (result)
		message = string.Format("{0} logged in.", this.userName);
	else
		message = string.Format("{0} not logged in.", this.userName);
	return result;
  }

  public string loginMessage() {
    return message;
  }

  public int numberOfLoginAttempts() {
    return loginAttempts;
  }
}
  • Compile it like before:
csc /t:library mytest.cs
|script|Login Dialog Driver|Bob|xyzzy|
|login with username|Bob|and password|xyzzy|
|check|login message|Bob logged in.|
|reject|login with username|Bob|and password|bad password|
|check|login message|Bob not logged in.|
|ensure|login with username|Bob|and password|xyzzy|
|show|number of login attempts|

The second line can also use this convention:

|login with username and password;|Bob|xyzzy|

Note the ';' at the end of the first value.

ScenariosEdit

Defining a scenarioEdit

using code:Edit

function LoginWithPassword( user, password )

using slim:Edit

method 1:

|scenario|Login|user|with password|password|

method 2:

|Login _ with password _|user,password|

Invoking a scenarioEdit

using code:Edit

LoginWithPassword( "bob", "foo" )

using slim:Edit

|Login with password|
|user|password|
|bob|foo|

ExampleEdit

Define a couple of scenarios:

|scenario|Login|user|with correct password|password|
|login with username|Bob|and password|@password|
|check|login message|Bob logged in.|
|ensure|login with username|Bob|and password|@password|
|show|number of login attempts|

|scenario|Login|user|with incorrect password|bad password|
|reject|login with username|Bob|and password|@bad password|
|check|login message|Bob not logged in.|
|show|number of login attempts|

Invoke the above scenarios (using a decision table)

|Login with correct password|
|user|password|
|Bob|xyzzy|

|Login with incorrect password|
|user|bad password|
|Bob|bad password 1|
|Bob|bad password 2|
|Bob|bad password 3|

Invoke the above scenarios (using a script table)

|Script|
|Login|Bob|with correct password|xyzzy|

Invoking the above scenario using a free-form style:

|Script|
|Login bob with correct password xyzzy|

Using Scenarios for BDD (Behavior Driven Development)Edit

Let's start with an example story:

Given a calculator
When I enter 3 and 4 and press plus
Then I should get 7


Enter the following on the test page:

|scenario|Given a calculator|

|Script|Calculator|

|scenario|When I enter _ and _ and press _|x,y,cmd|
|ensure|Perform Operation;|@cmd|@x|@y|

|scenario|Then I should get _|result|
|check|result|@result|

![ Script
Given a calculator
When I enter 3 and 4 and press plus
Then I should get 7
]!

Edit the C:\myfolder\mytest.cs file and add the following code:

public class Calculator {

     string _result;

     public bool PerformOperation(string cmd, string x, string y) {
	if ( cmd == "plus" )
	{
		_result = string.Format( "{0}", System.Convert.ToInt32(x) + System.Convert.ToInt32(y) );
		return true;
	}
	else
	{
		_result = "#n/a:";
		return false;
	}
     }

     public string result() {
	return _result;
     }
}

EchoEdit

Simple utility to echo back the value that's passed in. Used for testing fixtures. Enter the following on the test page:

|script|utility fixture|
|check|echo|4|3<_<9|
|check|echo|5|3<_<9|
|check|echo|6|3<_<9|
|check|echo|7|3<_<9|
|check|echo|8|3<_<9|
|check|echo|My name is Bob.|=~/B.b/|

Edit the C:\myfolder\mytest.cs file and add the following code:

public class UtilityFixture
{
    public string Echo(string s)
    {
        return s;
    }
}

SleepEdit

Simple utility to Sleep for a given period of time. Used for testing fixtures. Enter the following on the test page:

Sleep 200 milliseconds
|script|utility fixture|
|sleep;|200|milliseconds|

Sleep 1.5 seconds using milliseconds units.
|script|utility fixture|
|sleep;|1500|milliseconds|

Sleep 1.5 seconds using two waits
|script|utility fixture|
|sleep;|1|second|
|sleep;|500|milliseconds|

Sleep 1.5 seconds using seconds unit
|script|utility fixture|
|sleep;|1.5|seconds|

Sleep 1 second using minutes unit
|script|utility fixture|
|sleep;|0.02|minutes|

Sleep 1 second using hours unit
|script|utility fixture|
|sleep;|2.77e-4|hours|

Edit the C:\myfolder\mytest.cs file and add the following code:

public class UtilityFixture
{
    public void Sleep(double number, string unit)
    {
        const double    oneSecondInLongTicks = 10000000L;
        double          longTicks; // in 100-nanosecond increments
    
        if (unit.ToLower().Substring(0, 3) == "sec")
            longTicks = number * oneSecondInLongTicks;
        else if (unit.ToLower().Substring(0, 3) == "min")
            longTicks = number * oneSecondInLongTicks * 60L;
        else if (unit.ToLower().Substring(0, 4) == "hour")
            longTicks = number * oneSecondInLongTicks * 60L * 60L;
        else if (unit.ToLower().Substring(0, 3) == "mil")
            longTicks = number * oneSecondInLongTicks / 1000L;
        else
            throw new ArgumentException(string.Format("Unrecognized unit: '{0}'.  Use milliseconds, seconds, minutes or hours", unit));

        System.Threading.Thread.Sleep(new TimeSpan(Convert.ToInt64(longTicks)));
    }
}

QueryTableEdit

Enter the following on the test page:

!|Query:item list|
|employee number|first name|last name|hire date|
|1429|Bob|Martin|10-Oct-1974|
|8832|James|Grenning|15-Dec-1979|

Edit the C:\myfolder\mytest.cs file and add the following code:

using System.Linq;

public class ItemList
{
    private System.Collections.Generic.List<object> list(params object[] objs)
    {
        var list = new System.Collections.Generic.List<object>();
        list.AddRange(objs.AsEnumerable());
        return list;
    }

    public System.Collections.Generic.List<object> query()
    {
        return list(
            list(
                list("employee number", "1429"),
                list("first name", "Bob"),
                list("last name", "Martin"),
                list("hire date", "10-Oct-1974")
                ),
            list(
                list("employee number", "8832"),
                list("first name", "James"),
                list("last name", "Grenning"),
                list("hire date", "15-Dec-1979")
                )
            );
    }
}

Test SuitesEdit

TBD

Imports and Includes and LibrariesEdit

TBD

All ExamplesEdit

The entire C:\myfolder\mytest.cs looks like this:

using System.Linq;

public class MyFixture {
     public System.String Now() {
	return "12:00";
     }
}

namespace slim_example
{
  public class ShouldIBuyMilk
  {
    private int _cash;
    private int _pintsOfMilkRemaining;
    private string _useCreditCard;
 
    public void SetCashInWallet(int cash)
    {
      _cash = cash;
    }
 
    public void SetCreditCard(string useCreditCard)
    {
      _useCreditCard = useCreditCard;
    }
 
    public void SetPintsOfMilkRemaining(int pints)
    {
      _pintsOfMilkRemaining = pints;
    }
 
    public string GoToStore()
    {
      if (_cash > 0 || _useCreditCard.Equals("yes"))
        return "yes";
      return "no";
    }
  }
}

public class LoginDialogDriver {
  private string userName;
  private string password;
  private string message;
  private int loginAttempts;

  public LoginDialogDriver(string userName, string password) {
    this.userName = userName;
    this.password = password;
  }
  public bool loginWithUsernameAndPassword(string userName, string password) {
	loginAttempts++;
	bool result = userName == this.userName && password == this.password;
	if (result)
		message = string.Format("{0} logged in.", this.userName);
	else
		message = string.Format("{0} not logged in.", this.userName);
	return result;
  }

  public string loginMessage() {
    return message;
  }

  public int numberOfLoginAttempts() {
    return loginAttempts;
  }
}

public class Calculator {

     string _result;

     public bool PerformOperation(string cmd, string x, string y) {
	if ( cmd == "plus" )
	{
		_result = string.Format( "{0}", System.Convert.ToInt32(x) + System.Convert.ToInt32(y) );
		return true;
	}
	else
	{
		_result = "#n/a:";
		return false;
	}
     }

     public string result() {
	return _result;
     }
}

//////////////////////////////////////////////////////////////////////////////

public class ItemList
{
    private System.Collections.Generic.List<object> list(params object[] objs)
    {
        var list = new System.Collections.Generic.List<object>();
        list.AddRange(objs.AsEnumerable());
        return list;
    }

    public System.Collections.Generic.List<object> query()
    {
        return list(
            list(
                list("employee number", "1429"),
                list("first name", "Bob"),
                list("last name", "Martin"),
                list("hire date", "10-Oct-1974")
                ),
            list(
                list("employee number", "8832"),
                list("first name", "James"),
                list("last name", "Grenning"),
                list("hire date", "15-Dec-1979")
                )
            );
    }
}

The entire wiki text for FitNesse.MyProject looks like this:

!define TEST_SYSTEM {slim}
!path c:\myfolder\mytest.dll
!define COMMAND_PATTERN {%m -r fitSharp.Slim.Service.Runner,"c:\program files\fitsharp\fitsharp.dll" %p}
!define TEST_RUNNER {c:\program files\fitsharp\Runner.exe}

!|MyFixture|
|Now?|
|12:00|

|import|
|slim_example|
 
|Should I Buy Milk|
|cash in wallet|credit card|pints of milk remaining|go to store?|
|      0       |    no     |      0                |    no      |
|      10      |    no     |      0                |    yes     |
|      0       |    yes    |      0                |    yes     |
|      10      |    yes    |      0                |    yes     |
|      0       |    no     |      1                |    no      |

|script|Login Dialog Driver|Bob|xyzzy|
|login with username|Bob|and password|xyzzy|
|check|login message|Bob logged in.|
|reject|login with username|Bob|and password|bad password|
|check|login message|Bob not logged in.|
|ensure|login with username|Bob|and password|xyzzy|
|show|number of login attempts|

----

|scenario|Login|user|with correct password|password|
|login with username|Bob|and password|@password|
|check|login message|Bob logged in.|
|ensure|login with username|Bob|and password|@password|
|show|number of login attempts|

|scenario|Login|user|with incorrect password|bad password|
|reject|login with username|Bob|and password|@bad password|
|check|login message|Bob not logged in.|
|show|number of login attempts|

|Login with correct password|
|user|password|
|Bob|xyzzy|

|Login with incorrect password|
|user|bad password|
|Bob|bad password 1|
|Bob|bad password 2|
|Bob|bad password 3|


|Script|
|Login|Bob|with correct password|xyzzy|


|Script|
|Login bob with correct password xyzzy|


----

|scenario|Given a calculator|

|Script|Calculator|

|scenario|When I enter _ and _ and press _|x,y,cmd|
|ensure|Perform Operation;|@cmd|@x|@y|

|scenario|Then I should get _|result|
|check|result|@result|

![ Script
Given a calculator
When I enter 3 and 4 and press plus
Then I should get 7
]!

----
!|Query:item list|
|employee number|first name|last name|hire date|
|1429|Bob|Martin|10-Oct-1974|
|8832|James|Grenning|15-Dec-1979|

|script|echo fixture|
|check|echo|4|3<_<9|
|check|echo|5|3<_<9|
|check|echo|6|3<_<9|
|check|echo|7|3<_<9|
|check|echo|8|3<_<9|
|check|echo|My name is Bob.|=~/B.b/|

VariablesEdit

Creating a variableEdit

!define var {text}

or

!define var (text)

multi line variable:

!define myVariable {
This is the
text of my
variable
}

Referencing a variableEdit

${myVariable}

Example:

The value of the variable is: ${myVariable}.

If a variable is expressed on a page, but is not found, then its parent pages are searched in order, up to System.properties

TablesEdit

|Alpha|Beta|Gamma|
|1|2|3|

To prevent markup interpreted in the table, start the table with !, as in:

!|Alpha|Beta|Gamma|
|1|2|3|

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.