F# Running NUnit Tests - f#

I am looking to just run a few unit tests, I have added them them in an .fs file. I want to call them from the applications entry point as and when when I want to run them.
This the test I have written
namespace InvoiceApp
open System
open NUnit.Framework
open FsUnit
module Test =
let testPassed testName = printfn "Test Passed!! - %s" testName
let testFailed testName = printfn "Test Failed!! - %s" testName
[<TestFixture>]
type Test() =
[<TestCase(200,10,20)>]
let ``When profitmarging is 10% and total is 200 expect 20 `` x y z () =
try
Math.percentage x y |> should equal z
testPassed "When profitmarging is 10% and total is 200 expect 20"
with
| :? NUnit.Framework.AssertionException as ex ->
testFailed "When profitmarging is 10% and total is 200 expect 20"
printfn "%s" ex.Message
How can I call these tests from the entry point in a different .fs file?

A little while back I built an NUnit test runner as an F# module which should support your simple execution in a command line app scenario, see Running TAP.
To set it up, simply include this F# snippet and invoke the tests with:
Tap.Run typeof<InvoiceApp.Test>
Note: you will also need to change the test case to be a member function and use a non-generic tupled argument for either NUnit's built-in runner or the TAP runner to see it, i.e.
member test.``When profitmarging is 10% and total is 200 expect 20 `` (x:int,y:int,z:int) =

Take a look at SimpleTestRunner and RemoteTestRunner, ala this question.

Related

F# incorrect type and another incorrect type in the function call

Not sure what's off about this code. I want to use this as the main function to print a string or return not enough arguments. What's incorrect about this VS15 isn't very helpful in this instance.
[<EntryPoint>]
let main argv =
if (List.length argv) >= 1 then
printfn "Hello %s" argv.[0]; 0
else
printfn "Not enough arguments"; 1
main ["Test"]
Even though you didn't specify what error you get and where it appears (please always do that when asking questions), I can see what's wrong with your code: you're treating argv as if it was a List, but a .NET program entry point must accept an argument of type Array - specifically, array of strings - string[].
If you switch out List.length for Array.length, the function will compile.
[<EntryPoint>]
let main argv =
if (Array.length argv) >= 1 then
printfn "Hello %s" argv.[0]; 0
else
printfn "Not enough arguments"; 1
Now, if you want to call this function, you would want to supply an argument that is an array, not List. In F#, the brackets are used to denote a list. If you want to denote an array, you need to use bracket-pipes instead:
main [| "Test |]
EDIT in response to comment:
Normally you wouldn't need to "call" the entry point function explicitly. Entry point is the "start" of the program, there are no other functions calling it. This is why the entry point function must be the last function in the last file of the program. If you do place any code after the entry point, the compiler will give you an error.
The way you wrote the call main ["Test"], I assumed you just wanted to execute this call in F# interactive, which is a popular way of verifying your code without building and running it. Once you are ready to compile, you should remove this call.
Finally, I'd like to point out that you're actually accessing the array twice: first to check its length, then to fetch its first item. You can do both in one step using pattern matching:
[<EntryPoint>]
let main argv =
match argv with
| [|name|] -> printfn "Hello %s" name; 0
| _ -> printfn "Not enough or too many arguments"; 1
And look: this way, the program actually became slightly more valid. If you look closer, you'll notice that your original program accepts any number of arguments, but only actually uses the first one. This is a bit "unclean", so to say. The above version using pattern matching does one better: it will take exactly as many arguments as is needed for its function, or print an error message otherwise.

Property test ran as unit test fails even though it really passes

It appears that my property test that's running as a unit test fails even though it really passes.
The code is as follows:
module Tests.Units
open FsUnit
open NUnit.Framework
open NUnit.Core.Extensibility
open FsCheck.NUnit
open FsCheck.NUnit.Addin
open FsCheck
let add x y = (x + y)
let commutativeProperty x y =
let result1 = add x y
let result2 = add y x // reversed params
result1 = result2
[<Test>]
let ``When I add two numbers, the result should not depend on parameter order``()=
Check.Quick commutativeProperty |> should equal true
Summary:
Test Name: When I add two numbers, the result should not depend on
parameter order
Test FullName: Tests.Units.When I add two numbers, the result should
not depend on parameter order
Test Outcome: Failed
Result StackTrace: at
FsUnit.TopLevelOperators.should[a,a](FSharpFunc`2 f, a x, Object y) in
d:\GitHub\FsUnit\src\FsUnit.NUnit\FsUnit.fs:line 44
at Tests.Units.When I add two numbers, the result should not depend on
parameter order()
Result Message: Expected: true, but was
Result StandardOutput: Ok, passed 100 tests.
Am I reading this right?
What am I missing?
Use Check.QuickThrowOnFailure instead:
[<Test>]
let ``When I add two numbers, the result should not depend on parameter order``()=
Check.QuickThrowOnFailure commutativeProperty
Since it looks like you're attempting to run properties from within a unit testing framework like NUnit, you should consider to instead use one of the Glue Libraries for FsCheck:
FsCheck.Nunit
FsCheck.Xunit
This would enable you to write properties using the [<Property>] attribute:
[<Property>]
let ``When I add two numbers, the result should not depend on parameter order``x y =
let result1 = add x y
let result2 = add y x // reversed params
result1 = result2
Due to the poor extensibility API for NUnit, you can save yourself a lot of grief using xUnit.net instead of NUnit.

Why don't I see results of printfn called outside the main entrypoint (F#)

I have a F# console application that calls functions in other modules to perform its work from the main function entrypoint. I have a series of printfn in these other functions to provide me with information on the running of the program.
When compiled in DEBUG mode, all the statements print to the console. However, when compiled in RELEASE mode the only statements that print to the console are those that are directly inside the main entrypoint function.
What can I do to print statements for info in these other modules?
A code example is provided below:
Program.fs
[<EntryPoint>]
let main argv =
printfn "%s" "start" // prints in RELEASE and DEBUG mode
File1.Run
printfn "%s" "end" // prints in RELEASE and DEBUG mode
System.Console.ReadLine() |> ignore
0 // return an integer exit code
File1.fs
module File1
let Run =
let x = 1
printfn "%d" x // this won't print in RELEASE mode
yep you are (kindof) right - it will not print as Run is an expression here and it seems the compiler is optimizing it away in release mode.
And why should it not? In a perfect (pure/referential transparent) world you have an expression of type unit that can only have a single value () ... and you don't even use or remember the value!
To be honest I don't know if this is a bug or a feature ;)
anyway this simple trick will help you and indeed you should not use an expression with effects in the way you did:
let Run () =
let x = 1
printfn "%d" x
...
File1.Run ()
see - now it's a function and get's called at the right time and your output is back ;)
btw: if you are interested in this kind of stuff you an either use tools like Reflector (which I do not have at hand at the moment) or just use IL DASM (a tool VS should install anyway) - if you look at the compiled debug/release assemblies you will notice that nowhere something like this:
IL_001f: call class [FSharp.Core]Microsoft.FSharp.Core.Unit File1::get_Run()
can be found in the release version if you use the expression.
I played with it a bit and you have to get creative to make the compiler do this stuff:
For example
let reallyNeed v =
if v = ()
[<EntryPoint>]
let main argv =
printfn "%s" "start" // prints in RELEASE and DEBUG mode
File1.Run |> reallyNeed
printfn "%s" "end" // prints in RELEASE and DEBUG mode
System.Console.ReadLine () |> ignore
0 // return an integer exit code
works (it prints your 1) - while
ignore File1.Run
or
let reallyNeed v = ignore v
don`t ;) - seems like you have to actually use the value somewhere :D

300 milliseconds just for a variable declaration in F# Interactive?

I am playing with the F# Interactive Console and comparing the runtime of some numeric operations. On this code the total runtime seems to double only be repeating the declaration of one variable.
In VS 2010 I do:
open System.Diagnostics
let mutable a=1
Then I select this below and run it with Alt+Enter
let stopWatch = Stopwatch.StartNew()
for i=1 to 200100100 do
a <- a + 1
stopWatch.Stop()
printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds
it takes more or less: 320 ms
now i select this and hit Alt+Enter:
let mutable a=1
let stopWatch = Stopwatch.StartNew()
for i=1 to 200100100 do
a <- a + 1
stopWatch.Stop()
printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds
almost double: 620 ms
The same block but including the declaration at the top takes almost double. Shouldn't it be the same since I declare the variable before Stopwatch.StartNew() ? Does this have to do with the interactive console?
I have the same results using the #time directive.
I'm not convinced any of the answers yet are quite right. I think a is represented the same in both cases. And by that I mean an individual type is emitted dynamically wrapping that mutable value (certainly on the heap!). It needs to do this since in both cases, a is a top-level binding that can be accessed by subsequent interactions.
So all that said, my theory is this: in the first case, the dynamic type emitted by FSI is loaded at the end of the interaction, in order to output its default value. In the second case, however, the type wrapping a is not loaded until it is first accessed, in the loop, after the StopWatch was started.
Daniel is right - if you define a variable in a separate FSI interaction, then it is represented differently.
To get a correct comparison, you need to declare the variable as local in both cases. The easiest way to do that is to nest the code under do (which turns everything under do into a local scope) and then evaluate the entire do block at once. See the result of the following two examples:
// A version with variable declaration excluded
do
let mutable a=1
let stopWatch = Stopwatch.StartNew()
for i=1 to 200100100 do
a <- a + 1
stopWatch.Stop()
printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds
// A version with variable declaration included
do
let stopWatch = Stopwatch.StartNew()
let mutable a=1
for i=1 to 200100100 do
a <- a + 1
stopWatch.Stop()
printfn "stopWatch.Elapsed: %f" stopWatch.Elapsed.TotalMilliseconds
The difference I get when I run them is not measureable.

Comparing Discriminated Unions

I'm a newbie to F# and I'm playing around with FParsec. I would use FParsec to generate an AST. I would like to use FsUnit to write some tests around the various parts of the parser to ensure correct operation.
I'm having a bit of trouble with the syntax (sorry, the exact code is at work, I can post a specific example later) so how exactly could one compare two discriminated unions (one the expected, the other the actual result)? Could someone provide a tiny code example using FsUnit (or NUnit), please?
An example discriminated union (very simple)
type AST =
| Variable of string
| Class of string
| Number of int
Since, as Brian pointed out, F# unions have structural equality, this is easy using whichever unit testing framework you are fond of.
FsUnit is an F# specific library built on top of NUnit. My personal favorite F# specific unit testing library is Unquote, ;), which is framework agnostic, working very well with NUnit, xUnit.net, MbUnit, ... or even within FSI. You may be interested in this comparison with FsUnit.
So, how would you do this with NUnit + Unquote? Here's a full working example:
module UnitTests
open NUnit.Framework
open Swensen.Unquote
type AST =
| Variable of string
| Class of string
| Number of int
let mockFParsec_parseVariable input = Variable(input)
[<Test>]
let ``test variable parse, passing example`` () =
test <# mockFParsec_parseVariable "x" = Variable("x") #>
[<Test>]
let ``test variable parse, failing example`` () =
test <# mockFParsec_parseVariable "y" = Variable("x") #>
Then running the tests using TestDriven.NET, the output is as follows:
------ Test started: Assembly: xxx.exe ------
Test 'UnitTests.test variable parse, failing example' failed:
UnitTests.mockFParsec_parseVariable "y" = Variable("x")
Variable "y" = Variable("x")
false
C:\xxx\UnitTests.fs(19,0): at UnitTests.test variable parse, failing example()
1 passed, 1 failed, 0 skipped, took 0.80 seconds (NUnit 2.5.10).
An example - if you want to check the type but not the contents
let matched x=
match x with
|Variable(_) -> true
| _ -> false
Note here that you need a different function for each element of the discriminated union
If you want to compare equality, you can just do it in the standard way, like
Assert.AreEqual(Variable("hello"),result)
or
if result = Variable("hello") then stuff()

Resources