Can fitnesse validate non-xml output - fitnesse

I am using Rest Fixture with Fitnesse to make a GET request to url which returns non-xml response. Is there a way I could verify text/string (without xpath) in the content returned?

I found this solution.
TEXT is a supported content handler along XML and JSON. It is possible to override the content handler as TEXT and expect the content. Regular expression can also be used to expect content.
| Table:smartrics.rest.fitnesse.fixture.RestFixtureConfig | overridesContentHandlerConfig|
| restfixture.content.handlers.map | application/smil=TEXT |
!| Table:smartrics.rest.fitnesse.fixture.RestFixture | ${host} ||overridesContentHandlerConfig |
| GET | www.someurl.com | 200 | | [\s\w\d<>/=\:'.]*stringtoverify[\s\w\d<>/=\:'.]* |

You can use fit mode + NetRunner plugin (for .Net).
See here example, how to parse input line to the object.

Another way is to use Custom Comparators. This gives you more flexibility on customizing validation on custom/complicated results.
To use custom comparators:
documented here (search for 'CustomComparators')
required property: CustomComparators = <prefix:classname>[,<prefix:class name>]
motivation: The Slim protocol is all String values. It means that
comparison of an expected and actual result for complex datatypes is
limited to String equality or Regular Expression matching. If that is
not sufficient, a Custom Comparator can do more sophisticated
comparisons. Once registered, a Custom Comparator is triggered by its
prefix, followed by a colon, in front of the expected value.
Example Comparator implementation:
public class JSONAssertComparator implements CustomComparator {
#Override
public boolean matches(String actual, String expected) {
try {
JSONAssert.assertEquals(expected, actual, false);
return true;
} catch (JSONException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
Example plugins.properties:
CustomComparators = json:com.acme.JSONAssertComparator
Example ScriptTable usage:
|script|Customer |
|check|get|cust1|json:{id:cust1,name:"John Doe"}|

Related

Parameterizing a specflow step with keyword string from example step

I am new to specflow, want help with a specflow scenario like the one below.
Scenario Outline: Error messages validation for maximum allowed term rule
Given a <product>
When term exceeds the max allowed term
Then this <errormessage> is displayed
Examples:
| product | errormessage |
| ProductA | This is an error message 1 |
| ProductB | This is an error message 2 |
| ProductC | This is an error message 3 |
For the last step definition "*Then this errormessage is displayed " step, I want to reuse an existing binding method
"Then this (.) is displayed"
This existing binding method takes a string as a parameter (expected error message) and asserts it against the actual message picked form the app under test.
But when I use the method as is - its unable to pass the error message content as an array of strings . Would someone be able to help me to understand what do I need to do to make it work ?
Binding method example below . The step Then this is displayed is not able to recognize this binding, its asking me to write another method.
[Then(#"this ""(.*)"" is displayed")]
public void ThenErrorMessageIsDisplayed(string errorMessage)
{
var msg = uServiceSupport.GetMessages(responseData);
var found = new JObject();
// due to multiple error and warning messages
foreach (var elem in msg)
{
if (elem["message"].ToString().Contains(errorMessage))
found = (JObject)elem;
}
try
{
Assert.IsTrue(found.HasValues, "Check if response has warning/error message");
Assert.AreEqual(errorMessage, found["message"].ToString(), "Check if the error message is {0}", errorMessage);
}
catch (AssertionException)
{
Helper.LogInfo(string.Format("Response:\n {0}", JObject.Parse(responseData)));
throw;
}
}
The problem is in your step regex. you have this:
[Then(#"this ""(.*)"" is displayed")]
but you try and call it like this:
Then this <errormessage> is displayed
you do not have consistent usage of the ". you either need:
[Then(#"this (.*) is displayed")]
or
Then this "<errormessage>" is displayed

How to write fitnesse code for a method which accepts 2 parameters

I'm newbie to fitnesse and trying to run a simple calculator class which has "add" method accepting 2 parameters and returning the result. Can anyone help me to write the firnesse code for this, my method is as below
public int add(int a, int b) {
return a+b;
}
I believe you are trying to get a table like:
|AddFixtureTest |
|left|right|sum?|
|1 |1 |2 |
|2 |4 |6 |
This requires a java class like:
import fit.ColumnFixture;
public class AddFixtureTest extends ColumnFixture {
public int left;
public int right;
public int sum(){
return add(left, right);
}
private int add(int a, int b) {
return a+b;
}
}
See http://fitnesse.org/FitNesse.UserGuide.FixtureGallery.BasicFitFixtures.ColumnFixture
I assume Slim is fine by you and I'm gonna use script table for this (more out of habit):
|script| <class name> |
|add;| <variable1> | <variable2> |
As simple as that. And, make sure you are using the right libraries and pointing to the location of the where the class file is.
Example:
|import|
fitnesse.slim.test |
If you are interested in knowing why I have placed a semi-colon after "add", and how script table works, please go through this:
http://www.fitnesse.org/FitNesse.UserGuide.WritingAcceptanceTests.SliM.ScriptTable
You can get the FitNesse tutorial there for .Net code. I tried to describe how to use FitNesse for different types of testing.
If you want to check two parameters on the output you can do the following:
Return IEnumerable implementation with classes, which contains get
and set properties (see here). NetRunner will use get properties
if it can, otherwise it will use set properties. As a result, it will
set all available data first and then compare items left.
You can use out parameters in the tests, so you can return several different values and check them
The correct answer is:
|script:<classPackage>.<ClassName>|
|check|add;|8|8|16|
First tell the script to navigate to the correct class. In the next line you have to call either a method or a constructor. You can call the method by it's name (or fancy smansy digibetic words that vaguely match) and tack on a semicolon. But anything put into the pipe-blocks after that will be interpreted as parameters for that method. So how do you put the expected output?
The trick is to tell the FitNesse engine you need a result, with the keyword 'check'.
This will make the final pipe-block be the field for the expected result, in this case 16.
Here is a picture of the java code
Here is a picture of the text input and the FitNesse sceen result

FitNesse: Comparing data in Slim Test system

Table example:
!script|SomeTest |
|Goto |$Url |
|check |IsAt|IndexPage|true|
|Index |CheckUserOrder? |
|0 |Name1 |
|1 |Name2 |
Code example:
public class SomeTest {
public string index;
public bool IsAt(string pageTitle){
//function for checking title of page
}
public string CheckUserOrder{
return username(index); // will get name of user for list which is other class
}
}
An exception is thrown: method name '0' not found in SomeTest...
I don't know why FitNesse is considering '0' as a method and not a parameter.
Are you working with the Slim test system? ColumnFixture requires the Fit test system. http://fitnesse.org/FitNesse.UserGuide.TestSystems
With Slim test system, use the DecisionTable http://fitnesse.org/FitNesse.UserGuide.SliM.DecisionTable
So your test will look like:
!|script|SomeTest|
|Goto|$Url|
|check|IsAt|IndexPage|true|
!|SomeTest|
|Index|CheckUserOrder?|
|0|Name1|
|1|Name2|
You are trying to combine a script and a decission table. If you are doing a script table, I expect you would have:
!|script|SomeTest|
|Goto|$Url|
|check|IsAt|IndexPage|true|
|check|CheckUserOrder|0|Name1|
|check|CheckUserOrder|1|Name2|

Is there a way to inject support for the F# Option type into ServiceStack?

Updated below...
I recently started experimenting with ServiceStack in F#, so naturally I started with porting the Hello World sample:
open ServiceStack.ServiceHost
open ServiceStack.ServiceInterface
open ServiceStack.WebHost.Endpoints
[<CLIMutable; Route("/hello"); Route("/hello/{Name}")>]
type Hello = { Name : string }
[<CLIMutable>]
type HelloResponse = { Result : string }
type HelloService() =
inherit Service()
member x.Any(req:Hello) =
box { Result = sprintf "Hello, %s!" req.Name }
type HelloAppHost() =
inherit AppHostBase("Hello Web Services", typeof<HelloService>.Assembly)
override x.Configure container = ()
type Global() =
inherit System.Web.HttpApplication()
member x.Application_Start() =
let appHost = new HelloAppHost()
appHost.Init()
That works great. It's very concise, easy to work with, I love it. However, I noticed that the routes defined in the sample allow for the Name parameter to not be included. Of course, Hello, ! looks kind of lame as output. I could use String.IsNullOrEmpty, but it is idiomatic in F# to be explicit about things that are optional by using the Option type. So I modified my Hello type accordingly to see what would happen:
[<CLIMutable; Route("/hello"); Route("/hello/{Name}")>]
type Hello = { Name : string option }
As soon as I did this, the F# type system forced me to deal with the fact that Name might not have a value, so I changed HelloService to this to get everything to compile:
type HelloService() =
inherit Service()
member x.Any(req:Hello) =
box { Result =
match req.Name with
| Some name -> sprintf "Hello, %s!" name
| None -> "Hello!" }
This compiles, and runs perfectly when I don't supply a Name parameter. However, when I do supply a name...
KeyValueDataContractDeserializer: Error converting to type: Type
definitions should start with a '{', expecting serialized type
'FSharpOption`1', got string starting with: World
This wasn't a complete surprise of course, but it brings me to my question:
It would be trivial for me to write a function that can wrap an instance of type T into an instance of type FSharpOption<T>. Are there any hooks in ServiceStack that would let me provide such a function for use during deserialization? I looked, but I couldn't find any, and I'm hoping I was just looking in the wrong place.
This is more important for F# use than it might seem at first, because classes defined in F# are by default not allowed to be null. So the only (satisfying, non-hacky) way of having one class as an optional property of another class is with, you guessed it, the Option type.
Update:
I was able to sort-of get this working by making the following changes:
In the ServiceStack source, I made this type public:
ServiceStack.Text.Common.ParseFactoryDelegate
...and I also made this field public:
ServiceStack.Text.Jsv.JsvReader.ParseFnCache
With those two things public, I was able to write this code in F# to modify the ParseFnCache dictionary. I had to run this code prior to creating an instance of my AppHost - it didn't work if I ran it inside the AppHost's Configure method.
JsvReader.ParseFnCache.[typeof<Option<string>>] <-
ParseFactoryDelegate(fun () ->
ParseStringDelegate(fun s -> (if String.IsNullOrEmpty s then None else Some s) |> box))
This works for my original test case, but aside from the fact that I had to make brittle changes to the internals of ServiceStack, it sucks because I have to do it once for each type I want to be able to wrap in an Option<T>.
What would be better is if I could do this in a generic way. In C# terms, it would be awesome if I could provide to ServiceStack a Func<T, Option<T>> and ServiceStack would, when deserializing a property whose generic type definition matches that of the return type of my function, deserialize T and then pass the result into my function.
Something like that would be amazingly convenient, but I could live with the once-per-wrapped-type approach if it were actually part of ServiceStack and not my ugly hack that probably breaks something somewhere else.
So there are a couple of extensibility points in ServiceStack, on the framework level you can add your own Custom Request Binder this allows you to provide your own model binder that's used, e.g:
base.RequestBinders.Add(typeof(Hello), httpReq => {
var requestDto = ...;
return requestDto;
});
But then you would need to handle the model binding for the different Content-Types yourself, see CreateContentTypeRequest for how ServiceStack does it.
Then there are hooks at the JSON Serializer level, e.g:
JsConfig<Hello>.OnDeserializedFn = dto => newDto;
This lets you modify the instance of the type returned, but it still needs to be the same type but it looks like the F# option modifier changes the structural definition of the type?
But I'm open to adding any hooks that would make ServiceStack more palatable for F#.
What does the code look like to generically convert a normal Hello type to an F# Hello type with option?
The only thing I can think of is to replace the option type with your own type, one that has an implicit conversion from string to myOption, and anything else you need.
Not all that nice, but workable. Your type would probably also need to be serializable.
type myOption =
| None
| Some of string
static member public op_Implicit (s:string) = if s <> null then Some s else None
member public this.Value = match this with
| Some s -> s
| _ -> null
member this.Opt = match this with
| Some s -> Option.Some s
| None -> Option.None
Your record type would then be
[<CLIMutable>]
type Hello =
{ Name : myOption }
On the other hand, ServiceStack is open source, so maybe something could be done there.

Multiple fitnesse fixtures possible

Is it possible to use multiple fitnesse fixture classes in one testtable (a scriptable i.e.) as in something like the following?
|script|FixtureClassOne,FixtureClassTwo|
|AMethodInFixtureClassOne|2|
|AMethodInFixtureClassTwo|2|
This is possible. You should load the fixture as a library. E.g.:
| import |
| my.fixtures.classpath |
| library |
| fixture 1 |
| another fixture |
| script |
| etc. |
No need to provide a fixture after the 'script' identifier anymore.
You do have to be aware that if the fixtures share non-unique method names you get into trouble
Objective: To have Multiple Fixtures associated with a single HTML Test Case
How: As you are working with fitnesses HTML Test case, you probably have at least a single fixture associated with it, which we will call default Fixture.
But in order to access another fixture (where control of execution passes to the other fixture), write a method in the default fixture class:
public Fixture run(String str) {
try {
Fixture fixture = Fixture.loadFixture(str);
return fixture;
} catch (Throwable e) {
// put your error handling here
e.printStackTrace();
}
return null;
}
From the Test case, pass the fully specified location with the project to the run() method. When the run() method returns the fixture to the HTML test case, it passes its execution via the new Fixture.

Resources