Tuesday, November 2, 2010

Pilot - Unit Testing in F#

In this blog I want to talk about diverse subjects related to math and computer science. Nothing really prominent. Mostly small topics of interest to me. While must of this stuff will probably not be of great interest for anybody, who am I to decide that for you?
This is an experiment, and my first blog.


Today I want to start with a small piece of code that I wrote in F# language.
F# is an up and coming programing language being developed at Microsoft Research, and you can get it for free and do stuff on it. It is both, a functional and object-oriented language for .NET.


I wrote a small simple UnitTest class that you can use to help you test some simple functions. For now it provides some simple Assert methods. But the main type UnitTest gives you an easy way to just add more AssertFunctions.


First run this F# functions that you can use to print all the items in a given list:
(by the way, all this code below has some differences in line spacing with my original version because of the blog's editor. Those familiar with F# know that spacing matters.)


let rec PrintListBackWards list =
match list with
| head::tail -> PrintListBackWards tail
printfn "%s" (head.ToString())
| [] -> printf ""
;;

Then here you have the UnitTest function with its Asserts:


let AssertTrue a =
if a then true else false
;;
let AssertFalse a =
let a = not a
if a then true else false
;;
let AssertEquals a b =
if (a = b) then true else false
;;
let AssertNotEquals a b =
if a = b then false else true
;;
type UnitTest() =
let mutable pass = 0
let mutable fail = 0
let mutable backResults = []
let UpdateStats result =
let mutable strValue = ""
if result
then pass <- (pass + 1)
strValue <- "passed"
else fail <- (fail + 1)
strValue <- "failed"
strValue
backResults <- (strValue::backResults)
let ResultStatus voidArg =
if (fail = 0) 
     then if (pass = 0)
then -1
else 1
   else 0
member this.AssertTrue =
fun ( a ) -> let result = AssertTrue a
UpdateStats result
result
member this.AssertFalse =
fun ( a ) -> let result = AssertFalse a
UpdateStats result
result
member this.AssertIntEquals =
fun ( a : int, b : int ) -> let result = AssertEquals a b
UpdateStats result
result
member this.AssertIntNotEquals =
fun ( a : int, b : int ) -> let result = AssertNotEquals a b
UpdateStats result
result
member this.Print =
fun () -> let mutable result = ""
 let testResult = ResultStatus 0
 if (testResult < 0) 
 then result <- "NO EVALUTATIONS" 
 else if (testResult > 0)
  then result <- "PASSED"
  else result <- "FAILED"
 printfn ""
 printfn "---------- UNIT TEST RESULTS ----------"
 PrintListBackWards backResults
 printfn "-------------- %s ---------------" result
 printfn "pass = %d; fail = %d" pass fail
 printfn "----------------- END -----------------"
;;


Of course. I thought about creating a little test for you to see how you can run this:


let u = UnitTest();;
u.AssertTrue (true);;
u.AssertTrue (true);;
u.AssertTrue (false);;
u.AssertTrue (true);;
u.AssertFalse (true);;
u.AssertFalse (true);;
u.AssertFalse (false);;
u.AssertFalse (true);;
u.AssertIntEquals (3, 4);;
u.AssertIntEquals (3, 3);;
u.AssertIntNotEquals (4, 4);;
u.AssertIntNotEquals (4, 5);;
u.Print();;


As you can see, some of the assertions will return failure. For example: u.AssertIntEquals (3, 4);; has to fail, while u.AssertIntNotEquals (4, 5);; needs to pass.


So suppose you run all this pieces of code I gave you, in the same order. What should you get once you run the tests?


I ran all this from command line, and above you can see the nice format in which the unit test tool gives you a summary of the tests you ran.


Thanks for reading. I'll keep bringing some F# for a while and then I'll move to another topic.


To do: I need to find a way to stop the blog's editor from messing up the line spacing of the code snippets.

No comments:

Post a Comment