I am trying to unit test a parser that parses a string and returns the corresponding abstract syntax tree (represented as a discriminated union). I figured it would be pretty compact to use Xunit.Extensions' attribute InlineData to stack all test cases on one another:
[<Theory>]
[<InlineData("1 +1 ", Binary(Literal(Number(1.0)), Add, Literal(Number(1.0))))>]
...
let ``parsed string matches the expected result`` () =
However, compiler complains that the second argument is not a literal (compile time constant if I understand it correctly).
Is there a workaround for this? If not, what would be the most sensible way to structure parser result tests while keeping every case as a separate unit test?
One possibility is to use xUnit's MemberData attribute. A disadvantage with this approach is that this parameterized test appears in Visual Studio's Test Explorer as one test instead of two separate tests because collections lack xUnit's IXunitSerializable interface and xUnit hasn't added build-in serialization support for that type either. See xunit/xunit/issues/429 for more information.
Here is a minimal working example.
module TestModule
open Xunit
type DU = A | B | C
type TestType () =
static member TestProperty
with get() : obj[] list =
[
[| A; "a" |]
[| B; "b" |]
]
[<Theory>]
[<MemberData("TestProperty")>]
member __.TestMethod (a:DU) (b:string) =
Assert.Equal(A, a)
See also this similar question in which I give a similar answer.
Related
Take the following F# example:
let parse mapDate mapLevel mapMessge (groups : string list) =
{
DateTime =
mapDate(
groups.[2] |> Int32.Parse,
groups.[0] |> Int32.Parse,
groups.[1] |> Int32.Parse)
Level = mapLevel groups.[3]
Message = mapMessge groups.[4]
}
I can unit test the map functions independently that's ok, but how do I unit test that this function calls the functions passed in as arguments correctly?
In C# I would use mocks and verify the calls to them. I recently watched a pluralsight video that talked about how functional languages tend to use stubs instead of mocks. Here I could pass in a function that throws if it doesn't get the expected arguments but I'm not really sold on this approach.
I was just wondering if there were any patterns in functional programming in general for unit testing higher-order functions like this?
Well, let me disagree with given answer. Actually, there is a nice way to test higher order functions without even bothering about concrete types they might take (I consider typical HOF to be totally generic, however there is no difference: approach I suggest will work with more strict HFO rightly).
Let's take something really simple, something everyone is familiar with. How about ['t] -> ['t] function? It takes a single argument - a list of whatever type and returns list of the same type. Traditional OOP approach wouldn't work here: one need's to put a restriction on 't and test somewhat specific parameters of that type; the only way to make author to feel more confident with his implementation, is to increase unit tests numbers.
There is really great stuff named "category theory" in math. It's comparatively new filed of mathematics and studies things from the outside rather from than inside. In order to be able to describe things "from the outside" you need take a thing you're interested in and force it to interact with something you already know deep enough. Thus, category theory teaches to describe things in terms of their interrelations with other things. Can't we do the same here?..
Indeed, we can. That's actually quite easy: we got a f : ['t] -> ['t] already, but is there anything else such that we could make both interact and define something common - something that holds for each and every interaction regardless of any other factors? Let's take any g: 't -> 'y. Now we able to state: g (List.head (f ...) = List.head (List.map g (f ...)). I assume a certain argument of type ['t] to substitute .... Please note: given property is universal: it would hold for any pure functions composition of specified signatures regardless of their implementation. Also note how generic yet obvious it is: there are only two distinct "objects" interacting with each other via "composition", which could also be rewritten in terms of standard F#'s (|>), (<|) operators.
Now the fact is that for any higher order (pure) function there exists such kind of universal property; mostly, there are dozens of them. Thus one able to specify their properties in terms of composition (which is regular for FP) staying at the generic level. Having such a properties in the explicit form gives one chance to autogenerate hundreds of tests, based on inputs different not only by their values (which normally done by unit tests, except the fact they are rarely autogenerated), but also by types.
Pure functions are easier because you just have to test the outputs of your parse function. You shouldn't ever need to test using side effects like you do in imperative programming.
When writing most of your unit tests, you generally use the most simple possible for your function arguments, like identity or similar. Then you'd write one test named something like "mapLevel is applied to fourth group" where instead you make mapLevel something that's easy to recognize as changed, like toUpper. This lets you make sure you didn't accidentally copy/paste mapLevel to more than one output. Then a similar test for mapMessge.
Suppose we have a module that defines an abstract type T:
module AbstractType (T, lexer) where
data T = T String deriving Show
lexer = (fmap T) . words
(Note that we do not export any type constructors for T, so the user would not be able to draft an instance by hand.)
How does one unit test lexer function?
Sure we may use the Show property of T, like this:
module Main where
import AbstractType
main = test
(show $ lexer "summer is miles and miles away")
"[T \"summer\",T \"is\",T \"miles\",T \"and\",T \"miles\",T \"away\"]"
test :: (Eq a) => a -> a -> IO ()
test expression expectation
| expression == expectation = putStrLn "Test passed."
| otherwise = error "Test failed."
— But this is both not beautiful and unfit for cases when our abstract type is not an instance of a class that permits casting to another, constructable type.
Is there a remedy?
P.S. To provide some justification for the case: suppose we have a chain of functions like parser . lexer that we can integration test and see if the whole of it works. As the chain at hand gets more complex, it may nevertheless become desirable to unit test each link individually.
The example is a simplified excerpt from an actual toy text processor I am in the process of writing.
The generally accepted best practice is, for an exposed module A, to create an internal module A.Internal that is either:
Exposed but documented to be unstable or unsafe.
Not exposed to the users of the package, but only to the testing facilities. (This is made possible by the internal libraries feature released in Cabal 2.0.)
It is my understanding that functions that are not exposed enjoy more radical optimizations, particularly inlining. I am not sure if it applies to functions in internal libraries too.
On the other hand, situations often arise when a user desperately needs some internal feature of your library and ends up forking and patching it to gain access. This is, of course, unfortunate and undesirable.
I would say generally that the implementation of an abstract type is best kept in an internal library as a safety measure, but you should use your judgement in each particular case.
(Mandatory Newbie Disclaimer)
I'm trying to write a rule that fires whenever an object within a (scala) list matches a condition. The issue here is that the list is actually an Option(List[TypeA])... (Also, I realise it isn't best practice to store lists in working memory, but I can't do otherwise given the circumstances)
The case classes I'm using have the following sort of structure:
TypeA {
arg1 : Option[List[TypeB]]
}
with
TypeB {
value : String
}
I've written a rule similar to this:
when
$a : TypeA($l : arg1)
$b : TypeB() from $l.get()
then
System.out.println($b)
I've tried this out without the ".get()" only to get an object of type Some().
Using the ".get()", I have managed to return the contents of the Option but it doesn't seem to match the expected type (List[TypeB]). Instead the type of the value returned seems to be scala.collection.immutable.$colon$colon
Any ideas on what the problem is? And if there is any proper way to handle Options in Drools?
Since you are doing a lot of Java and Scala interop, I suggest you make yourself very familiar with the Scala's javaconverters functionality. This handy collection of utilities allows you to convert Scala collections to Java collection and vice versa.
In your case, I think you need to convert from a Java collection to a Scala collection. Try the following:
import scala.collection.JavaConverters._
val myScalaList = $b.asScala.toList
Example from the documentations:
import scala.collection.JavaConverters._
val sl = new scala.collection.mutable.ListBuffer[Int]
val jl : java.util.List[Int] = sl.asJava
val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala
assert(sl eq sl2)
An additional problem you have is that of mutable and immutable data structures. The standard list structure in Java is mutable but by default Scala offers you an immutable list unless you explicitly indicate that you want a mutable list. Therefore, there will be some impedance mismatch when doing naive conversions between the two worlds.
As I have mentioned in an earlier post, you can avoid yourself many issues by creating Java classes for the entities that you need to push into Drools. Mixing Java classes with Scala classes in Scala based projects is not an issue.
An alternative method is to create a function in your Scala case class which converts the Scala collection to a Java collection using the asJava method and returns it. In your DRL file whenever you need to reference that scala collection, call this method so that you get a Java collection instead.
Ideally, JBoss Drools, if they so choose, need to either enhance their current compiler to deal with Scala types better or make a dedicated Drools Scala compiler which will not mangle the Scala types.
The only thing I can think of to try:
when
$a : TypeA($l : arg)
$b : TypeB() from (ArrayList)$l.get() // or some other Java *-List
then
System.out.println($b)
Worth another try:
when
$a : TypeA($l : arg)
$b : TypeB() from $l.get()asJava()*-List
then
System.out.println($b)
Let's say we have a class
type ThisClassIsComplicated () =
let calculateSomething a b =
a + b
In this case calculateSomething is trivial, but if it would be more complicated it may make sense to verify that the calculations done there are correct.
It might make sense to use a unit testing framework to test that private methods.
My question: how to unit test private methods in F#?
Some random thoughts:
The selected answer here, suggests to use the InternalsVisibleTo attribute which anyway is applicable only to internalmethods.
What is the route specific to F# if any? Is this better in a F# design?
let calculateSomething a b = a + b
type ThisClassIsComplicated () =
member this.Calculate a b = calculateSomething a b
Maybe the scope of calculateSomething could be even narrowed down by having a nested module.
If you feel like your code is too complicated to test it from the outside, use the latter option. And in case you want to test an inner function like
let myComplicatedOperation input =
let calculateSomething a b =
a + b
calculateSomething (fst input) (snd input)
you can always rewrite it with currying like this:
let myComplicatedOperation calculateSomething input =
calculateSomething (fst input) (snd input)
Your question does not seem to be directly related to F# though. The general way to test private methods is typically by extracting a class (or, in F#, you can also just extract a let bound function). And making your testee public on that other class / function.
I think that loosening access restrictions in a class/module to facilitate testing is often a bad idea. If you have decided something is irrelevant to know for the outside world, you wanting to test it doesn't make it any less irrelevant.
Can't you just have a public method/function in your class/module that does the testing?
type ThisClassIsComplicated () =
let calculateSomething a b =
a + b
member private this.TestInstance () =
printfn "%A" <| calculateSomething 1 2
static member Test () =
(new ThisClassIsComplicated()).TestInstance()
You can use Impromptu Interface to invoke private methods.
For example, I test the function calcNodeLabel at
https://code.google.com/p/fseye/source/browse/trunk/FsEye/Forms/WatchTreeView.fs#73 like so: https://code.google.com/p/fseye/source/browse/trunk/Test.FsEye/WatchTreeViewLabelCalculatorTests.fs#54
But you need to be careful testing hidden functions in F#: it's an implementation detail of the compiler how the function will actually be compiled (e.g. as a method, as a delegate, as a ...).
Folks will warn generally against testing private methods, but I think it is a bit simplistic to say "never test private methods", since such a declaration takes for granted that access levels as specified in the .NET framework are the only way they could be.
For example, calcNodeLabel in my example should indeed be hidden from the great wide world, but I would consider it part of the internal contract of the class. Of course, you could argue that the class view data and the view itself should be separated, but the point stands: all models are imperfect!
I have a bunch of F# functions that implement different algorithms for the same input, kind of like the Strategy pattern. To pick the right strategy, I want to pattern match on the input argument and return the function as a value :
let equalStrategy points : seq<double> =
...
let multiplyStrategy factor (points: seq<double>) =
...
let getStrategy relationship =
match relationship with
| "=" -> equalStrategy
| "*5" -> multiplyStrategy 5.0
| _ -> raise (new System.NotImplementedException(" relationship not handled"))
Now I want to write some unit tests to make sure that I return the right strategy, so I tried something like this in nUnit :
[<TestCase("=")>]
[<Test>]
member self.getEqualstrategy( relationship:string ) =
let strategy = getStrategy relationship
Assert.AreEqual( strategy, equalStrategy )
Now I think the code is correct and will do what I want, but the assertion fails because functions don't seem to have an equality operation defined on them. so my questions are :
(a) is there a way to compare 2 functions to see if they are the same, i.e. let isFoo bar = foo == bar, that I can use in an nUnit assertion?
or
(b) is there another unit testing framework that will do this assertion for me in F#?
Testing whether an F# function returned by your getStrategy is the same function as one of the funcions you defined is also essentially impossible.
To give some details - the F# compiler generates a class that inherits from FSharpFunc when you return a function as a value. More importantly, it generates a new class each time you create a function value, so you cannot compare the types of the classes.
The structure of the generated classes is something like this:
class getStrategy#7 : FSharpFunc<IEnumerable<double>, IEnumerable<double>> {
public override IEnumerable<double> Invoke(IEnumerable<double> points) {
// Calls the function that you're returning from 'getStrategy'
return Test.equalStrategy(points);
}
}
// Later - in the body of 'getStrategy':
return new getStrategy#7(); // Returns a new instance of the single-purpose class
In principle, you could use Reflection to look inside the Invoke method and find which function is called from there, but that's not going to be a reliable solution.
In practice - I think you should probably use some other simpler test to check whether the getStrategy function returned the right algorithm. If you run the returned strategy on a couple of sample inputs, that should be enough to verify that the returned algorithm is the right one and you won't be relying on implementation details (such as whether the getStrategy function just returns a named function or whether it returns a new lambda function with the same behaviour.
Alternatively, you could wrap functions in Func<_, _> delegates and use the same approach that would work in C#. However, I think that checking whether getStrategy returns a particular reference is a too detailed test that just restricts your implementation.
Functions doesn't have equality comparer:
You will have error: The type '('a -> 'a)' does not support the 'equality' constraint because it is a function type
There is a good post here
It would be very difficult for the F# compiler to prove formally that two functions always have the same output (given the same input). If that was possible, you could use F# to prove mathematical theorems quite trivially.
As the next best thing, for pure functions, you can verify that two functions have the same output for a large enough sample of different inputs. Tools like fscheck can help you automate this type of test. I have not used it, but I've used scalacheck that is based on the same idea (both are ports from Haskell's QuickCheck)