5 Reference - essenius/FitNesseFitSharpRest GitHub Wiki
When you create a set of test cases for a project, there are some things that will be the same across. You can specify these in the configuration fixture Rest Config, which is a table table.
Configuration Item | Meaning | Value if not specified |
---|---|---|
ContentTypeMapping | See description below | application/xml: xml application/json: json default: json |
DefaultAccept | Default Accept header | application/xml,application/json;q=0.9,/;q=0.8 |
DefaultContentType | Default content type for the request | application/json |
DefaultUserAgent | User agent that the fixture identifies itself as | FitNesseRest |
DefaultXmlNameSpaceKey | see description below | Atom |
Encoding | Content encoding | iso-8859-1 |
Headers | Additional request headers | Empty |
Proxy | Web proxy (can be System, None or a URL) | System |
Timeout | Timeout in seconds | 10 |
XmlValueTypeAttribute | see description below | Empty |
The DefaultXmlNameSpaceKey is used in case an XML file has an implicit name space, which usually happens with Atom files. The example XML response below [from OData Atom] shows two explicit namespaces with prefixes d (xmlns:d=
) and m (xmlns:m=
), and an implicit namespace (xmlns=
).
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<entry xml:base="http://services.odata.org/OData/OData.svc/"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
<id>http://services.odata.org/OData/OData.svc/Categories(0)</id>
<title type="text">Food</title>
<updated>2010-03-10T10:43:51Z</updated>
<author>
<name />
</author>
<link rel="edit" title="Category" href="Categories(0)" />
<link
rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Products"
type="application/atom+xml;type=feed" title="Products"
href="Categories(0)/Products" />
<category term="ODataDemo.Category"
scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:ID m:type="Edm.Int32">0</d:ID>
<d:Name>Food</d:Name>
</m:properties>
</content>
</entry>
The issue with implicit name spaces is that XPath queries look for entities without name spaces by default, and because of this implicit namespace, none of the entities are found if you search for them without a namespace prefix. So, the following won’t work:
| $id= | value from response matching | XPath: /entry/id |
Instead, we need a name space prefix to refer to. So, if we use the default value atom
, the query that does work will become:
| $id= |value from response matching | XPath: / atom:entry/atom:id |
If you don’t like the default value or if there is a conflict with another namespace, you can use DefaultXmlNameSpaceName
to set the default namespace to another value.
By default, any XML element is a string, so if you ask for the type via any of the fixtures, it will always give back System.String as the type. However, if you e.g. look at the OData example in the previous section, you will see in the last part of above XML document that this format specifies the data type in an attribute called m:type
. This shows that the field d.ID
has a type of Edm.Int32
. By specifying the attribute that the fixture needs to look at in the XmlValueTypeAttribute
, you can make it return this value. If that attribute is not there, then it will simply return its native type System.String
. The default value is empty, which means it won’t use any attributes to try and determine the data type.
The fixture uses the returned content type to figure out whether the content is XML, Json or Text. You can configure which content types map to XML and which map to Json. You can also set a default. The standard setting maps application/xml
to XML, application/json
to Json and plain/text
to Text. Other content types will be mapped to Json. As per the standard value in the table, each entry is expected on a line of its own; the content types are separated from their mappings with a colon (:) just like with the headers.
Rest Tester is a Script fixture. It can be instantiated with a parameter (the endpoint URL) or without, in which case the endpoint needs to be set via the Endpoint property.
The fixture has the following functions:
Properties are functions that you can use for both set and get operations. If it helps for readability you can prepend the fixture with Set or Get to make the operation explicit, but it is not mandatory. If the property operation has a parameter then it is assumed to be a set, and otherwise it is a get. Set operations do not return a value, and get operations obviously return the value of the property.
End Point | |
---|---|
Description: | Sets or gets the end point for the service (base URL) |
Example(s): | | End Point | http:/mymachine.mydomain.com | | $endPoint= | End Point | |
Request Body | |
---|---|
Description: | Sets or gets the payload for the REST request |
Example(s): | | Set Request Body | {"value":"test data"} | | $body= | Request Body | | show | Get Request Body | |
Unlike properties, functions only support one operation: get, set or execute a command. You can’t add get
or set
to them. Convention is that setters already have an explicit set. Getters don’t, because it reads more naturally to have a line like |show|Response| than |show|Get Response|.
Request Headers | |
---|---|
Description: | Returns the request headers |
In: | Optional list of headers to return the values from, in the standard FitNesse list format |
Out: | the request headers separated by new-line (\n) in a string. Format is key: value . |
Example(s): | | show | Request Headers | [Content-Type, Content-Length] | |
Request Headers Without | |
---|---|
Description: | Returns the request headers except for those in the list |
In: | list of headers that should not be shown. |
Out: | the request headers separated by new-line (\n) in a string. Format is key: value.
|
Example(s): | | show | Request Headers Without | [Authorization] | |
Response | |
---|---|
Description: | Returns the response payload (serialized to string). Can only be used after executing a Send To command |
In: | - |
Out: | the response string |
Example(s): |
Response Code | |
---|---|
Description: | Return the HTTP response code of the REST request |
In: | - |
Out: | the (numerical) response code. |
Example(s): | | check | Response Code | 201 | |
Response Code Description | |
---|---|
Description: | Return a description of the HTTP response code |
In: | - |
Out: | the (numerical) response code. |
Example(s): | | check | Response Code Description | Created | |
Response Headers | |
---|---|
Description: | Returns the response headers |
In: | Optional list of headers to return the values from (FitNesse list format) |
Out: | the response headers separated by new-line (\n) in a string. Format is key: value . |
Example(s): | | show | Response Headers | [Content-Type, Content-Length, Date] | |
Response Headers Without | |
---|---|
Description: | Returns the response headers except for those in the list |
In: | list of headers that should not be shown. |
Out: | the request headers separated by new-line (\n) in a string. Format is key: value . |
Example(s): | | show | Response Headers Without | [WWw-Authenticate] | |
Response Object | |
---|---|
Description: | Try to create a Json, XML or Text object from the response by parsing the response string |
In: | - |
Out: | the response object which can be used as parameter in content handlers and other fixtures |
Example(s): | | $responseObject= | Response Object | |
Send To [With Body] | |
---|---|
Description: | Send a REST request to an endpoint |
In: | the verb (GET, POST, etc.), the relative URL to the service[, payload] in cased of With Body |
Out: | whether or not the operation succeeded |
Example(s): | | Send | Get | to | /posts/1| | Send | POST | to | /posts | with body | {"body"":"test"} | |
Set Request Header To | |
---|---|
Description: | Set a request header |
In: | the request header to be set, the value to be assigned |
Out: | - |
Example(s): | | Set Request Header | Content-Type | To | application/json | |
Value From Request Header Matching | |
---|---|
Description: | Extracts a value from a request header using a regular expression (regex) matcher. In the expression, use parentheses () to indicate the section to be extracted. |
In: | request header, match expression |
Out: | the matched value |
Example(s): | |$format=|Value from request header|Accept|matching|application/(.+)| |
Note: | Sometimes request headers don’t get set until just before the request gets executed. An example is Content-Length, so you can only interrogate that after the REST call has been made. |
Value From Response Header Matching | |
---|---|
Description: | Extracts a value from a response header using a regular expression (regex) matcher. In the expression, use parentheses () to indicate the section to be extracted. |
In: | response header to be examined, the match expression |
Out: | the matched value |
Example(s): | |$len=| Value from response header |Content-Length| matching |(\d+)| |
Value From Response Matching | |
---|---|
Description: | Extracts a value from a response using a matcher. It uses Regex, XPath or Json query based on the Content-Type. |
In: | the match expression |
Out: | the matched value |
Example(s): Text: JSON: XML: |
| $id= | Value from response matching | "ResponseText":"(\d+)" | | $id= | Value from response matching | ResponseText | | $id= | Value from response matching | //a:entry[1]//d:Id | |
The Properties for Object fixture can be used in a decision table, a query table and a table table to check and/or set property values of content objects.
In a decision table, you can record multiple expectations for values of properties. In XML objects, you specify the properties (elements) you are interested in via an XPath query. With Json objects, you use a JPath expression. For Text objects, you can use regular expressions. Note that Text objects are immutable – access is read-only. The columns that the decision table supports are shown in below Table
Column | Use | Description |
---|---|---|
Property | Input | XPath, JPath or regular expression to identify the property (based on the type of object) |
Value | Input/Output | Value of the property (output only for Text objects) |
Type | Output | The property type. Exact values depend on object type (Json, XML, Text). Text objects infer the type from the value. |
Value was set | Output | Whether the value of the property was changed by this line |
Some examples using a Json object:
!|decision: properties for object|$testobject |
|Property |Type? |Value? |
|StringArray |Array |["hi","there"]|
|DecimalValue |Float |300.5 |
|StringValue |String|string value |
|DoubleValue |Float |~=3.14159 |
Here we use the decision table only to check types and values of several properties that happen to have names identifying their .Net types. Column names ending with question marks are fixture outputs, and others are inputs. The Property
field is the identification, and that is always an input field. The Type
field is always an output field, and Value
can be both. It is used here as output, so you can use it to check the current values against an expectation.
If you use Value
as input, then the fixture will try to set the value. The Value Was Set
column reports whether the value was actually changed. Here is an example:
!|decision: properties for object|$testobject |
|Property |Value |Value was set?|Type?|
|NonExistingValue |irrelevant value |false | |
|GuidValue |CAFECAFE-CAFE-CAFE-CAFE-CAFECAFECAFE|true |Guid |
|DateValue |23-02-1965 16:10 |true |Date |
This capability only works for properties that exist already, so you can’t create properties in this way, only update their value.
You can also use the Value column twice (once as input and once as output) – then the output will be the value after assignment. Note that this behavior is irrespective of where you place the column in the table. FitNesse first handles all input columns, and then all output columns.
!|decision: properties for object|$testobject |
|Property |Value |Value was set?|Value?|
|LongValue |9007199254740992|true | |
|DecimalValue |450.3 |true | |
|ShortValue |-32768 |true | |
|StringValue |clean code |true | |
The Properties for Object
fixture also exposes a Query interface. This means you can also use it in query tables and subset query tables. You use the column names Property
, Type
and Value
, as in the decision table. Value was set
is not available since the query table is read only.
If you want to check the whole set of properties you can use the query table; if you only want to check a few properties and ignore the rest you use the subset table.
Example of a subset table which checks types and values of 3 properties:
!|subset query: properties for object|$testobject |
|Property |Type |Value |
|LongValue |Integer|9007199254740992 |
|StringValue |String |clean code |
|GuidValue |Guid |cafecafe-cafe-cafe-cafe-cafecafecafe|
With an extra parameter in the header (a JPath expression for Json objects, an XPath expression for XML objects or a regular expression for Text objects), you can define the scope of the properties to be checked . Note that we now use a query and not a subset query – so these are all the properties matching the JPath expression StringArray
:
!| query: properties for object|$testobject|StringArray |
|Property |Type |Value |
|StringArray |Array |["hi","there"]|
|StringArray[0] |String |hi |
|StringArray[1] |String |there |
For Text objects, we simulate properties via groups in regular expressions. Since these simulated properties don’t have names, we replace them by a regular expression that exactly gives the Xth result, where x is the match number. The property types are inferred from the value. Below example shows a query extracting all numbers, and the words true and numbers, executed on a Text object $obj
with content contains 21, 3000000000, 51.6 and no other true numbers
.
!define regex {((\b\d+(\.\d+)?)|true|numbers)}
!define multiregex {(?:${regex}.*?)}
|query:properties for object|$obj |${regex} |
|Property |Type |Value |
|${multiregex}!-{1}-! |System.Int32 |21 |
|${multiregex}!-{2}-! |System.Int64 |3000000000|
|${multiregex}!-{3}-! |System.Double |51.6 |
|${multiregex}!-{4}-! |System.Boolean|true |
|${multiregex}!-{5}-! |System.String |numbers |
To dissect the regular expression a bit:
Regex | Meaning |
---|---|
( | Start of group to be matched |
( | Start of group matching numbers |
\\b| Word boundary
\\d+| One or more digits
(\\.\\d+)?| Zero or one occurrences of a group of a dot and one or more digits (i.e. fraction)
)|End of group matching numbers | |Alternative true| Text true | | Alternative numbers | Text numbers ) | End of group to be matched
You can also use this way of simulating properties in Text objects with decision tables:
|decision:properties for object|$obj |
|Property |Type? |Value?|
|${multiregex}!-{3}-! |System.Double|51.6 |
If you only want to see the properties with their types and values, you can use the table table. Its header is very similar to the query table, and you don’t need to specify any columns; they will be filled in automatically. So if you specify
!|table: properties for object|$testobject|StringArray|
the result will be similar to:
The Content handler script gives access to handling of content in Json an XML format, and also to some extent in text format. It does not have parameters.
The language used for locators/queries is dependent on the content type, as per the table below
Format | Language | Example | Note |
---|---|---|---|
JSON | JPath | Customer[12].Addr.Id | First is 1 |
XML | XPath | /a:feed/a:entry[3]//m:properties/d:Id | First is 0 |
TEXT | Regex | Content-Length: (/d+) | Returns value between () |
These are the available instructions in the Content Handler fixture:
Add To At | |
---|---|
Description: | Add the content of an object into another object |
in: | the object to add, the object to be added to, the locator where it needs to be added |
Out: | whether or not the operation succeeded |
Example(s): | | Add | $contributor | to | $article | at | //a:entry[2]//m:properties | | Add | World | to | |
Classes In | |
---|---|
Description: | Return a list of classes in an assembly |
In: | the path to the assembly |
Out: | list of classes in that assembly |
Example(s): | | show | classes in | RestTests.dll | |
Create Object From | |
---|---|
Description: | Create a new object from a string. It will establish the format by trying to parse it into each of the supported formats, and using the format for which parsing succeeds. |
In: | the string to be transformed |
Out: | the object, to be assigned to a FitNesse symbol |
Example(s): | | $body= | Create Object From | {} | |
Note: | Parsing a string to text always succeeds. So if the string can’t be parsed to Json or XML, it will return as a Text object |
Create Object From | |
---|---|
Description: | Create a new object of a specified type from a string |
In: | the required object type, the string to be transformed |
Out: | the object, to be assigned to a FitNesse symbol |
Example(s): | | $body= | create | text | object from | {} | |
Note: | Valid values for object type are json, text and xml |
Create Object From Type In Assembly [With Params] | |
---|---|
Description: | Create an object modeled after a class in a .Net assembly |
In: | the required object type, the name of the class, the assembly name [, the parameter list] |
Out: | the object, to be assigned to a FitNesse symbol |
Example(s): | | Create | json | object from type | RestTests.ManyTypes | in assembly | RestTests.dll | |
Note: | Valid values for object type are json, text and xml |
Delete From | |
---|---|
Description: | Delete a property |
In: | the property query,the object to be used |
Out: | whether or not the operation succeeded |
Example(s): | | delete | StringArray[1] | from | $testobject | |
Evaluate On | |
---|---|
Description: | Evaluate a query (regex for Text, JPath for Json, XPath for XML) |
In: | the evaluate query, the object to be used |
Out: | the result of the evaluation |
Example(s): | | $result= | evaluate |/a/b[@class=’q’]| on | $testobject | |
Load Object From | |
---|---|
Description: | Create a new object from file content. It will establish the format by trying to parse it into each of the supported formats, and using the format for which parsing succeeds. |
In: | the path to the file |
Out: | the object to be assigned to a FitNesse symbol |
Example(s): | | $body= | Load Object From | c:\data\test.json | |
Note: | If the file contains binary data, an ArgumentException will be thrown. If the file does not contain binary data and can’t be parsed to Json or XML, it will return as a Text object. |
Properties Of | |
---|---|
Description: | Return locators to all properties of a certain element in the object |
In: | the object to be used, the property query to start |
Out: | a list of locators (unique paths to the properties) |
Example(s): | | show | properties | Customer.addr |of | $response | |
Property Set Of Contains Value Like | |
---|---|
Description: | Return whether any of the specified properties contain a value matching the specified glob (with *? wildcards). |
In: | the property query (can be empty, then "all" is assumed), the object to be used, the glob pattern to match |
Out: | whether or not the value of any of the specified properties matches the glob pattern |
Example(s): | | property set | "(.*?)" | of | $textObject | contains value like | Test | |
Property Type Of | |
---|---|
Description: | Return the type of a property |
In: | the property query, the object to be used |
Out: | the property type (null if not found) |
Example(s): | | $type= |property type | Customer.id |of | $response | |
Property Value Of | |
---|---|
Description: | Return the value of a property |
In: | the property query, the object to be used |
Out: | the property value (null if not found) |
Example(s): | | $id= |property value | Customer.id |of | $response | |
Set Property Value Of To | |
---|---|
Description: | Set the value of an existing property |
In: | the required property query, the object to be used, the new value |
Out: | whether or not the operation succeeded |
Example(s): | | set property value | Customer.addr.city | of | $response | to | Rotterdam | |
Note: | Cannot be used to create new properties, only change the value of existing ones |