Running Tests ...
21 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteDefaultCellHandlerTests.TestBlankAndNullKeywords
8 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteDefaultCellHandlerTests.TestBooleanSymbols
3 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteDefaultCellHandlerTests.TestErrorKeyword
6 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteDefaultCellHandlerTests.TestExceptionKeywordHandler
5 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteDefaultCellHandlerTests.TestFailKeyword
4 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteDefaultCellHandlerTests.TestSaveAndRecallSymbols
1 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteOptionalAndCustomHandlerTests.TestCustomHandler
41 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteOptionalAndCustomHandlerTests.TestHandlerLoader
6 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteOptionalAndCustomHandlerTests.TestRangeHandlers
27 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.SuiteOptionalAndCustomHandlerTests.TestSubstringHandlers
18 right, 0 wrong, 0 ignored, 0 exceptions
SuiteCellHandlerTests.TestQuerySymbols
6 right, 0 wrong, 0 ignored, 0 exceptions
SuiteFitServerTests.TestPathParser
4 right, 0 wrong, 0 ignored, 0 exceptions
SuiteFixtureTests.TestActionFixture
2 right, 0 wrong, 0 ignored, 0 exceptions
SuiteFixtureTests.TestExecuteOnColumnFixtures
8 right, 0 wrong, 0 ignored, 0 exceptions
SuiteFixtureTests.TestFixtureParameters
7 right, 0 wrong, 0 ignored, 0 exceptions
SuiteFixtureTests.TestImportFixture
1 right, 0 wrong, 0 ignored, 0 exceptions
SuiteFixtureTests.TestRowFixture
3 right, 0 wrong, 18 ignored, 0 exceptions
SuiteFixtureTests.TestTableFixture
3 right, 0 wrong, 0 ignored, 0 exceptions
SuiteFixtureTests.TestWhiteSpace
18 right, 0 wrong, 0 ignored, 0 exceptions
SuiteTypeConversionTests.TestArrayConversion
3 right, 0 wrong, 0 ignored, 0 exceptions
SuiteTypeConversionTests.TestCustomTypeConversion
2 right, 0 wrong, 0 ignored, 0 exceptions
SuiteTypeConversionTests.TestEnumConversion
39 right, 0 wrong, 0 ignored, 0 exceptions
SuiteTypeConversionTests.TestPrimitiveTypeConversion
3 right, 0 wrong, 0 ignored, 0 exceptions
TestCustomType
3 right, 0 wrong, 0 ignored, 0 exceptions
TestFieldsPropertiesAndMethods
20 right, 0 wrong, 0 ignored, 0 exceptions
TestGracefulFixtureNames
9 right, 0 wrong, 0 ignored, 0 exceptions
TestGracefulMemberNames
Test Output
Empty cells should display the value of a field or property. If a cell contains "blank" or "null" then treat it as blank ("") or truly null.
Empty cells are automatically filled with the value of the field or property, and no check is performed. To explicitly set a value to empty string ("") or null, or to check for empty string or null, use the "blank" and "null" keywords.
| blank and null keyword column fixture | |||||
| field | field | field? | field? | is field null? | is field blank? |
| null | null | null | null | true | false |
| blank | blank | blank | blank | false | true |
| joe | joe | joe | joe | false | false |
| null | null | null | null | true | false |
public class BlankAndNullKeywordFixture : ColumnFixture
{
public string Field;
public bool IsFieldNull() {return Field == null;}
public bool IsFieldBlank() {return Field != null && Field.Length == 0;}
}
| blank and null keyword row fixture |
| field |
| null |
| blank |
| joe |
public class BlankAndNullKeywordRowFixture : RowFixture
{
public override object[] Query()
{
BlankAndNullKeywordColumnFixture domainObject1 = new BlankAndNullKeywordColumnFixture();
domainObject1.Field = null;
BlankAndNullKeywordColumnFixture domainObject2 = new BlankAndNullKeywordColumnFixture();
domainObject2.Field = "";
BlankAndNullKeywordColumnFixture domainObject3 = new BlankAndNullKeywordColumnFixture();
domainObject3.Field = "joe";
return new object[]{domainObject1, domainObject2, domainObject3};
}
public override Type GetTargetClass()
{
return typeof(BlankAndNullKeywordColumnFixture);
}
}
| action fixture | |||
| start | string fixture | ||
| enter | field | null | enter value |
| check | field | null | check with empty cell |
| check | field | null | check expected value |
| enter | field | null | enter with empty cell (should do nothing) |
| check | field | null | check with empty cell |
| check | field | null | check expected value |
| action fixture | ||
| start | string fixture | |
| enter | field | blank |
| check | field | blank |
| check | field | blank |
| enter | field | blank |
| check | field | blank |
| check | field | blank |
| action fixture | ||
| start | string fixture | |
| enter | field | joe |
| check | field | joe |
| check | field | joe |
| enter | field | joe |
| check | field | joe |
| check | field | joe |
FitNesse treats "y" or "yes" (case insensitive) as true and "n" or "no" as false for bools.
| bool fixture | ||||
| field | field? | field? | field? | field? |
| true | Y | y | Yes | yes |
| false | N | n | No | no |
Use the "error" keyword when you expect an error. In this case, an error turns the cell a nice shade of green!
| error throwing fixture | ||
| error throwing method() | error throwing property() | redirect to error throwing method() |
| error | error | error |
In addition to the "error" keyword, you can use the "exception" keyword to specify that an exception with a specific message and/or of a specific class is thrown.
Works with just messages
| exception throwing fixture | ||
| message | throw null reference exception! | throw application exception! |
| this is the message | exception["this is the message"] | exception["this is the message"] |
.. or just the class name
| exception throwing fixture | ||
| message | throw null reference exception! | throw application exception! |
| this is the message | exception[NullReferenceException] | exception[ApplicationException] |
.. or both!
| exception throwing fixture | ||
| message | throw null reference exception! | throw application exception! |
| this is the message | exception[NullReferenceException: "this is the message"] | exception[ApplicationException: "this is the message"] |
This is primarily necessary to test Fitnesse itself. We need the ability to show that Fitnesse will correctly fail a test when comparing different expected and actual values, but we need that test to turn GREEN so we don't have failing tests!
Works for primatives
| int fixture | |
| field | field? |
| 21 | fail[37] |
Works for strings
| string fixture | |
| field | field? |
| some value | fail[some other value] |
Works for objects (people)
| person fixture | |
| field | field? |
| Joe Smith | fail[Joe Smithe] |
You can even use the fail keyword to prove that the fail keyword works. In this test, we wrap "fail[Joe Smith]" inside a fail - so when the application returns a person named "Joe Smith", which fails to fail (get it?), the test PASSES!
| person fixture | |
| field | field? |
| Joe Smith | fail[fail[Joe Smith]] |
And this one shows that "Joe Smith" (correctly) does not equal "failure[Joe Smith]"
| person fixture | |
| field | field? |
| Joe Smith | fail[failure[Joe Smith]] |
You can save values in arbitary symbols and recall them later
NOTE: This functionality works differently from similar functionality in java FitNesse. The plan is to add this approach to the java version in an upcoming release.
In the first column, set the value of the field. In the second, query for the value of that field (indicated by the column header ending with "?") and store that value in the symbol "id".
| string fixture | |
| field | field? |
| 3 | >>id |
In another table (for the purposes of demonstration - this would work fine in one table) recall the value of the symbol "id" and assign it to the field in the first column. In the second column, query for the value of field (field?) and assert that its value is what was submitted in the previous table..
| string fixture | |
| field | field? |
| <<id | 3 |
This works for fields, properties and methods...
| string fixture | |||||
| field | field? | property | property? | set | get? |
| 1 | >>a | 2 | >>b | 3 | >>c |
| string fixture | |||||
| field | field? | property | property? | set | get? |
| <<a | 1 | <<b | 2 | <<c | 3 |
You can easily create and load your own custom handlers.
Here's how we added the IntegralRangeHandler to FitNesse, which you use to assert that an int value returned from the application is within a given range.
First, we overrode the Match method, which takes a string (the contents of a cell) and a Type. In this example, we want an int followed by ".." followed by an int in the string AND the Type of the field must also be an int. It is very important that the Match method be as unique as possible. For example, there are three substring handlers: substring (..abc..), starts with (abc..) and ends with (..abc). The Match method on the StartsWithHandler needs to ensure that the text ends with ".." and does NOT start with "..".
The second thing you must do is override the Check method (you can also override Input, Save, Recall and Execute methods, though these are far less useful). In this example, we test that the actual int is >= the left number and <= the right number in the expression.
public class IntegralRangeHandler : DefaultCellHandler
{
public override bool Match(string searchString, Type type)
{
return type == typeof (int) && Regex.IsMatch(searchString, "^-?[0-9]*\\.\\.-?[0-9]*$");
}
public override void HandleCheck(Fixture fixture, Parse cell, Accessor accessor)
{
if (IsInRange(Actual(accessor, fixture), LowEnd(Args(cell)), HighEnd(Args(cell))))
{
fixture.Right(cell);
}
else
{
fixture.Wrong(cell, accessor.Get(fixture).ToString());
}
}
private string[] Args(Parse cell)
{
return cell.Text().Split('.');
}
private int Actual(Accessor accessor, Fixture fixture)
{
return (int) accessor.Get(fixture);
}
private int HighEnd(string[] args)
{
return Convert.ToInt32(args[args.Length - 1]);
}
private int LowEnd(string[] args)
{
return Convert.ToInt32(args[0]);
}
private bool IsInRange(int actual, int low, int high)
{
return actual >= low && actual <= high;
}
}To use this handler, load it using the CellHandlerLoaderFixture...
| cell handler loader | |
| load | integral range handler |
or load it within your own fixture...
public class CustomFixture : ColumnFixture {
public CustomFixture {
CellOperation.LoadHandler(new IntegralRangeHandler());
}
...
}
and then use it!
| int fixture | |
| field | field? |
| 39 | 37..42 |
Lastly, this clears all the cell handlers and loads the defaults. This is not required, but if you use a lot of custom handlers you may run into matching collisions (i.e. two Match methods that both return true for the same expression). Clearing them is advisable.
| cell handler loader |
| clear |
| loadDefaults |
You can manipulate the list of loaded cell handlers using the CellHandlerLoaderFixture.
Here are the defaults.
| cell handler inspector |
| Name |
| DefaultCellHandler |
| BlankKeywordHandler |
| NullKeywordHandler |
| ErrorKeywordHandler |
| EmptyCellHandler |
| BoolHandler |
| SymbolSaveHandler |
| SymbolRecallHandler |
| FailKeywordHandler |
| ExceptionKeywordHandler |
Now clear the handlers..
| cell handler loader |
| clear |
and the list should be empty.
| cell handler inspector |
| Name |
No reload the defaults..
| cell handler loader |
| loadDefaults |
and they should all be in the list.
| cell handler inspector |
| Name |
| DefaultCellHandler |
| BlankKeywordHandler |
| NullKeywordHandler |
| ErrorKeywordHandler |
| EmptyCellHandler |
| BoolHandler |
| SymbolSaveHandler |
| SymbolRecallHandler |
| FailKeywordHandler |
| ExceptionKeywordHandler |
Add an optional handler..
| cell handler loader | |
| load | SubstringHandler |
and it should be in the list.
| cell handler inspector |
| Name |
| DefaultCellHandler |
| BlankKeywordHandler |
| NullKeywordHandler |
| ErrorKeywordHandler |
| EmptyCellHandler |
| BoolHandler |
| SymbolSaveHandler |
| SymbolRecallHandler |
| FailKeywordHandler |
| ExceptionKeywordHandler |
| SubstringHandler |
Remove a single handler..
| cell handler loader | |
| remove | SubstringHandler |
and it should not be in the list.
| cell handler inspector |
| Name |
| DefaultCellHandler |
| BlankKeywordHandler |
| NullKeywordHandler |
| ErrorKeywordHandler |
| EmptyCellHandler |
| BoolHandler |
| SymbolSaveHandler |
| SymbolRecallHandler |
| FailKeywordHandler |
| ExceptionKeywordHandler |
You can assert that a numeric value is within a given range using the optional IntegralRangeHandler.
First, make sure to load the handler as it is not loaded by default.
| cell handler loader | |
| load | IntegralRangeHandler |
Type the low end of the range, ".." and the high end and the cell will turn green if the actual value is within that range.
| int fixture | |||||
| field | field? | property | property? | set | get? |
| 256 | 0..256 | 5 | 4..7 | 9 | 3..9 |
| 0 | -12..37 | -19 | -256..0 | -1 | -12..12 |
You can assert that a returned value contains a given substring, or specifically starts or ends with that substring.
Coincidentally, this will work for the string representation of any type (excluding arrays).
- use ..abc.. to assert that the returned value contains "abc"
- use abc.. to assert that the returned value starts with "abc"
- use ..abc to assert that the returned value ends with "abc"
| cell handler loader | |
| load | SubstringHandler |
| load | StartsWithHandler |
| load | EndsWithHandler |
| string fixture | |||||
| field | field? | property | property? | set | get? |
| abcdef | ..bcd.. | ghijk | ..hi.. | lmnop | ..no.. |
| abcdef | abc.. | ghijk | gh.. | lmnop | lm.. |
| abcdef | ..def | ghijk | ..jk | lmnop | ..op |
| int fixture | |||||
| field | field? | property | property? | set | get? |
| 12345 | ..234.. | 12345 | ..234.. | 12345 | ..234.. |
| 12345 | 123.. | 12345 | 123.. | 12345 | 123.. |
| 12345 | ..345 | 12345 | ..345 | 12345 | ..345 |
| person fixture | |||||
| field | field? | property | property? | set | get? |
| john doe | ..john.. | dr suess | ..sue.. | sam iam | ..m i.. |
| john doe | john.. | dr suess | dr s.. | sam iam | sam.. |
| john doe | ..doe | dr suess | ..ess | sam iam | ..am |
The DotNet FitServer treats "()", "?" and "!" as indications that you are trying to access information (for fields, properties and methods).
| string fixture | |||
| field | field! | field? | field() |
| aValue | aValue | aValue | aValue |
| anotherValue | anotherValue | anotherValue | anotherValue |
| string fixture | |||
| property | property! | property? | property() |
| aValue | aValue | aValue | aValue |
| anotherValue | anotherValue | anotherValue | anotherValue |
| string fixture | |||
| set | get! | get? | get() |
| aValue | aValue | aValue | aValue |
| anotherValue | anotherValue | anotherValue | anotherValue |
The PathParser is used by the .NET FitServer to parse the path passed to it from FitNesse. You can include a config file on the path, and .NET FitServer will use that config file during the test run.
Try just one path entry...
Now two...
Now one assembly and one config file
Try just one path entry...
| path parser fixture | ||
| path string | assembly paths? | config file path? |
| c:\path\to\assembly.dll | c:\path\to\assembly.dll | null |
Now two...
| path parser fixture | ||
| path string | assembly paths? | config file path? |
| c:\path\to\assembly.dll;c:\path\to\other\assembly.dll | c:\path\to\assembly.dll,c:\path\to\other\assembly.dll | null |
Now one assembly and one config file
| path parser fixture | ||
| path string | assembly paths? | config file path? |
| c:\path\to\assembly.dll;c:\path\to\assembly.config | c:\path\to\assembly.dll | c:\path\to\assembly.config |
An ActionFixture allows you to set values, get values and call methods repeatedly within the same fixture. The first row has one cell with "Action Fixture". The subsequent rows can have 2 or 3 cells:
start in the left most cell names the fixture that you'll test using ActionFixture?
check in the left most cell will test the value of the field named in the second cell with the value in the third cell
press will execute the method named in the second cell
enter will assign the value of the third cell to the the field or property named in the second cell
| Action Fixture. | ||
| start | Count Fixture | |
| check | Counter | 0 |
| press | Count | |
| check | Counter | 1 |
| press | Count | |
| check | Counter | 2 |
| enter | Counter | 5 |
| press | Count | |
| check | Counter | 6 |
public class CountFixture : Fixture {
private int counter = 0;
public void Count() {
counter++;
}
public int Counter {
set { counter = value; }
get { return counter; }
}
}
Column Fixtures have a virtual Execute() method which is called before the first output operation in a given row. You can override this method to handle some processing after input/before output.
| ExecuteExampleFixture | |
| int field | int field? |
| 1 | 2 |
| 2 | 4 |
public class ExecuteExampleFixture : ColumnFixture
{
public int IntField;
public override void Execute()
{
IntField = IntField*2;
}
}
In a row fixture or column fixture, any cells in the first row after the cell with the name of the fixture, are treated as arguments against parameters defined within the fixture.
As shown in both of these examples, you access the text in these cells using a protected IList named Args:
| parameterized column fixture | string value | 2 | true | Joe Zawinul |
| string field? | int field? | bool field? | person field? | |
| string value | 2 | true | Joe Zawinul | |
using fit;
namespace fitnesse.acceptanceTests
{
public class ParameterizedColumnFixture : ColumnFixture
{
public string StringField;
public int IntField;
public bool BoolField;
public Person PersonField;
public override void Execute()
{
StringField = (string) new TypeAdapter(typeof(string)).Parse(Args[0]);
IntField = (int) new TypeAdapter(typeof(int)).Parse(Args[1]);
BoolField = (bool) new TypeAdapter(typeof(bool)).Parse(Args[2]);
PersonField = (Person) new TypeAdapter(typeof(Person)).Parse(Args[3]);
}
}
}| parameterized row fixture | string value | 2 | True | Joe Zawinul |
| value | ||||
| string value | ||||
| 2 | ||||
| True | ||||
| Joe Zawinul | ||||
using System;
using System.Collections;
using fit;
namespace fitnesse.acceptanceTests
{
public class ParameterizedRowFixture : RowFixture
{
public override object[] Query()
{
ArrayList list = new ArrayList();
list.Add(new ValueWrapper(new TypeAdapter(typeof(string)).Parse(Args[0])));
list.Add(new ValueWrapper(new TypeAdapter(typeof(int)).Parse(Args[1])));
list.Add(new ValueWrapper(new TypeAdapter(typeof(bool)).Parse(Args[2])));
list.Add(new ValueWrapper(new TypeAdapter(typeof(Person)).Parse(Args[3])));
return list.ToArray();
}
public override Type GetTargetClass()
{
return typeof(ValueWrapper);
}
}
public class ValueWrapper
{
private object value;
public ValueWrapper(object value)
{
this.value = value;
}
public object Value
{
get { return value.ToString(); }
}
}
}The DotNet FitServer will look for your Fixture in any of the namespaces defined in an Import table.
By default, the DotNet FitServer includes the "fit" namespace. This test suite includes the "fitnesse.acceptanceTests" namespace in the SetUp fixture, and clears all namespaces (except "fit") after each test in the TearDown fixture.
Show that only "fit" and "fitnesse.acceptanceTests" are present. (If there are any other namespaces present already, this table will show a failure).
| Namespace Inspector |
| Namespace |
| fit |
| fitnesse.acceptanceTests |
| fitnesse.handlers |
Add "some.namespace".
| Import |
| some.namespace |
Show that "some.namespace" is present.
| Namespace Inspector |
| Namespace |
| fit |
| fitnesse.acceptanceTests |
| fitnesse.handlers |
| some.namespace |
Row fixtures work correctly with arrays.
| ArrayOfStringsFixture | |
| field | save! |
| a,b,c | null |
| ArrayOfStringsRowFixture |
| field |
| a,b,c |
Convenient access to table cells.
Sometimes you just want a fixture that lets you access the cells in a table by row and column. TableFixture? provides some simple methods that allow just that.- The (row,column) coordinates are zero based,
- with (0,0) being the upper left cell.
The methods of TableFixture? are:
| Comment | |
protected abstract void DoStaticTable(int rows) |
TableFixture is an abstract class that you must derive from. You must override DoStaticTable to perform the functions of the fixture. The number of rows in the table is passed in rows. |
protected Parse GetCell(int row, int column) |
Returns the addressed table cell as a Parse. |
protected String GetText(int row, int column) |
Returns the text within the addressed table cell. |
protected int GetInt(int row, int column) |
Converts the text within the addressed cell to an int and returns it. |
protected boolean Blank(int row, int column) |
Returns true if the addressed table cell is blank. |
protected void Right(int row, int column) |
Turns the addressed table cell green. |
protected void Wrong(int row, int column) |
Turns the addressed table cell red. |
protected void Wrong(int row, int column, string actual) |
Turns the addressed table cell red, and annotates it with the actual value. |
protected void Ignore(int row, int column) |
Turns the addressed cell gray. |
| Bowling Game Fixture | |||||||||||||||||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
| 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 150 |
| Bowling Game Fixture | |||||||||||||||||||||
| 10 | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 10 | 300 | |||||||||
If you want a string value to include leading or trailing whitespace, use the syntax for escaping literals:
precede it with !-
follow it with -!
for example, " value" would be represented as !- value-!
| string | ||
| field | field? | |
| value | value | "value" |
| value | value | " value" |
| value | fail[value] | " value" fails against "value" |
The .NET Fit server will handle arrays of primitive and custom types
| array of ints | |||||
| field | field? | property | property? | set | get? |
| 1,2,3 | 1,2,3 | 4,5,6,7 | 4,5,6,7 | 9,0 | 9,0 |
| array of strings | |||||
| field | field? | property | property? | set | get? |
| 1,2,3 | 1,2,3 | 4,5,6,7 | 4,5,6,7 | 9,0 | 9,0 |
| this, is, an, array, of, strings | this, is, an, array, of, strings | this, is, an, array, of, strings | this, is, an, array, of, strings | this, is, an, array, of, strings | this, is, an, array, of, strings |
| array of bools | |||||
| field | field? | property | property? | set | get? |
| true | true | false | false | true | true |
| false, true, false | false, true, false | false, true, false | false, true, false | false, true, false | false, true, false |
| array of people | |||||
| field | field? | property | property? | set | get? |
| john doe, jane roe | john doe, jane roe | first last, first last | first last, first last | c sharp, dot net | c sharp, dot net |
The .NET Fit server will instantiate an instance of any class that exports a static Parse method that accepts a string and overrides ToString().
| person fixture | |||||
| field | field? | property | property? | set | get? |
| john doe | john doe | jane roe | jane roe | do remi | do remi |
public class PeopleFixture : ColumnFixture
{
public Person Field;
public Person Property
{
get { return Field; }
set { Field = value; }
}
public Person Get() {
return Field;
}
public void Set(Person value) {
Field = value;
}
}
public class Person
{
private string firstName;
private string lastName;
public static Person Parse(string name)
{
string[] names = name.Split(' ');
return new Person(names[0], names[1]);
}
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public override string ToString()
{
return firstName + " " + lastName;
}
}
!Row Fixtures can correctly handle the values in an enum.
| color inspector |
| ToString() |
| Red |
| Blue |
public enum Color
{
Red,
Blue
}
public class ColorInspectorFixture : RowFixture
{
public override object[] Query()
{
Array colorsArray = Enum.GetValues(typeof(Color));
ArrayList colorsList = new ArrayList(colorsArray);
return colorsList.ToArray();
}
public override Type GetTargetClass()
{
return typeof(Color);
}
}The .NET Fit server will handle any numeric or boolean primitive types.
| int fixture | |||||
| field | field? | property | property? | set | get? |
| 0 | 0 | 0 | 0 | 0 | |
| 123 | 123 | 456 | 456 | 789 | 789 |
| long fixture | |||||
| field | field? | property | property? | set | get? |
| 0 | 0 | 0 | 0 | 0 | |
| 123 | 123 | 456 | 456 | 789 | 789 |
| double fixture | |||||
| field | field? | property | property? | set | get? |
| 0 | 0.0 | 0 | 0.0 | 0.0 | |
| 12.3 | 12.3 | 37.42 | 37.42 | 98.452 | 98.452 |
| float fixture | |||||
| field | field? | property | property? | set | get? |
| 0 | 0.0 | 0 | 0.0 | 0.0 | |
| 12.3 | 12.3 | 37.42 | 37.42 | 98.452 | 98.452 |
| decimal fixture | |||||
| field | field? | property | property? | set | get? |
| 0 | 0.0 | 0 | 0.0 | 0.0 | |
| 12.3 | 12.3 | 37.42 | 37.42 | 98.452 | 98.452 |
| bool fixture | |||||
| field | field? | property | property? | set | get? |
| False | false | False | false | false | |
| false | false | true | true | false | false |
| true | true | false | false | true | true |
FitNesse will handle any type that implements a static Parse(string) method and overrides ToString().
Parse(string) should construct and return an instance of the Type. The trick is that the ToString() method must produce the same string that was used to create the instance.
string str = "some meaningful string representation of a domain object"; DomainObject instance = DomainObject.Parse(str); Assert.AreEqual(str, instance.ToString());
| person fixture | three amigos | ||||
| field | field? | property | property? | set | get? |
| Grady Booch | Grady Booch | Ivar Jacobson | Ivar Jacobson | Jim Rumbaugh | Jim Rumbaugh |
public class Person
{
private string firstName;
private string lastName;
public static Person Parse(string name)
{
string[] names = name.Split(' ');
return new Person(names[0], names[1]);
}
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public override string ToString()
{
StringBuilder builder = new StringBuilder(firstName);
if (builder.Length > 0 && lastName != null && lastName.Length > 0)
{
builder.Append(" ");
}
return builder.Append(lastName).ToString();
}
}
public class PersonFixture : ColumnFixture
{
public Person Field;
private Person propertyValue;
private Person methodValue;
public Person Property
{
set { propertyValue = value; }
get { return propertyValue; }
}
public void Set(Person value)
{
methodValue = value;
}
public Person Get()
{
return methodValue;
}
}The DotNet FitServer allows you to assign values to public fields, properties or setter methods (methods that accept one argument and return void), and retrieve values from public fields, properties or getter methods (methods that return a non-void value and accept no arguments).
This way the business owners (who write the tables) need not concern themselves with implementation details, while developers (who write the fixtures) need not code to inadvertantly imposed business rules like whether a public member should be exposed through a method or a property.
| string fixture | |||||
| field | field? | property | property? | set | get? |
| field value | field value | property value | property value | method value | method value |
public class StringFixture : ColumnFixture
{
public string Field;
public string Property
{
get { return propertyValue; }
set { propertyValue = value; }
}
public void Set(string value)
{
methodValue = value;
}
public string Get()
{
return methodValue;
}
private string propertyValue;
private string methodValue;
}The DotNet FitServer allows you to name fixtures gracefully, so you can type "add employee" rather than "namespace.AddEmployeeFixture".
All of the following tables access the fitnesse.acceptanceTests.NamespaceInspector which reports all the namespaces that are currently loaded.
| fit.NamespaceInspector |
| namespace |
| fit |
| fitnesse.acceptanceTests |
| fitnesse.handlers |
| NamespaceInspector |
| namespace |
| fit |
| fitnesse.acceptanceTests |
| fitnesse.handlers |
| Namespace Inspector |
| namespace |
| fit |
| fitnesse.acceptanceTests |
| fitnesse.handlers |
| namespace inspector |
| namespace |
| fit |
| fitnesse.acceptanceTests |
| fitnesse.handlers |
| Namespace Inspector. |
| namespace |
| fit |
| fitnesse.acceptanceTests |
| fitnesse.handlers |
| Namespace-Inspector |
| namespace |
| fit |
| fitnesse.acceptanceTests |
| fitnesse.handlers |
This one will find "ActionFixture" and "CountFixture" (looking for classes whose names end with "Fixture")
| action | ||
| start | count | |
| check | counter | 0 |
| press | count | |
| check | counter | 1 |
The DotNet FitServer allows you to name class members (fields, properties and methods) gracefully ("calculate tax!" rather than "CalculateTax!")
| member finder test | |||||
| the field | the field? | the property | the property? | the setter method | the getter method? |
| first value | first value | second value | second value | third value | third value |
| member finder test fixture | |||||
| The Field | The Field? | The Property | The Property? | The Setter Method | The Getter Method? |
| first value | first value | second value | second value | third value | third value |
| MemberFinderTestFixture | |||||
| THE-FIELD | THE-FIELD? | THE?&#PROPERTY | THE+-=PROPERTY? | The*Setter*Method | The*Getter*Method? |
| first value | first value | second value | second value | third value | third value |