CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Matthew Podwysocki

Life of a Functional Programmer
  • 2008 – The Year that Was

    I know if I were to do a retrospective, it should have been last week, but now is as good a time as any.  2008 was a busy year for myself that I managed to challenge myself and push myself in many different ways.  From joining CodeBetter to speaking at conferences, there has been a lot of things going on.  I’ll focus on three areas, the personal, local and more global levels.

    The Personal

    On the personal level, 2008 was a bit of an interesting year.  Lately, there has been a large focus on Haskell here along with my usual postings on functional programming in general.  That’s going to continue of course as I try to take on a title like Erik Meijer’s “Language Pimper” (great business card BTW).  I’ve followed the Pragmatic Programmer guys suggestion of learning a new language every year.  Last year I had a focus on Erlang, Ruby, Haskell among others in more of the functional side.  So, what’ll it be this year? 

    Not to be only technical, but I’ve picked up a lot of the Lean Software Development ideas lately and have been reading the Corey Ladas Scrumban book as well as following the groups and conversations on the topic.  With the presentation at DC ALT.NET on Kanban to my other readings, there is still so much yet to explore.

    The Local

    The Washington, DC developer community has been active this past year.  With such groups as the NoVA Languages group, FringeDC , the local Ruby groups (DCRUG, NovaRUG) and of course the .NET groups (CapArea.NET, CMAP, RockNUG, etc) have been active and quite rewarding experiences.  Given the opportunity to speak at some of these events were a great experience.

    Running the DC ALT.NET group has been a lot of fun moving into our second year of operation.  With such topics ranging from Common Lisp, Ruby, Selenium to Kanban, we’ve covered a broad range of topics that you won’t find at many other user groups.  This year will be no different with exploration into service buses, acceptance testing, TDD among other topics.

    The strength of the Ruby community here in the DC area has been great to see with events such as RubyNation and  and RubyDCamp.  Also, the Northern Virginia Languages group (novalang) and FringeDC have been fulfilling my language fix from Erlang, to Scheme and now to Haskell where the novalang group is co hosting the Real World Haskell Book Club.

    The Global

    As for the more global events?  The ALT.NET Open Spaces, Seattle was a great event that I was glad to be a member.  Subsequently at the Continuous Improvement in Software Conference (KaizenConf), there were even more interesting conversations especially around many of the ideas coming from Lean Software Development.  Getting an opportunity to talk about functional programming in both was a lot of fun and best of all, I learned a lot through teaching as well.  I’ve found that to be a pretty effective way for me at least to gain further insight.  My hope is that these events continue and to further the discussions and some of the ideas that have been core to the movement.

    QCon San Francisco was another great event to be able to share ideas with some in the Haskell community, DDD community among others and a good number of my CodeBetter peers.  It was also a great experience to accompany Don Syme to talk about F# with the Bay Area Functional Programmers Group.   I highly recommend QCon as an event to attend.

    What’s In Store for 2009?

    So, what’s in store for 2009?  Well, I already have a bit of a busy schedule for the next month such as the following:

    This is going to be an exciting year of challenges!  What are you doing this year to challenge yourself?

  • [ANN] The Real World Haskell Book Club Starts 1/5/2009

    real_world_haskell

    Just as a reminder, the Real World Haskell book club starts on 1/5/2009 at 2000 hours EST (0100 GMT).  This group is intended to be an online group that holds sessions weekly on Mondays to discuss the book but as well to create some hacking projects along the way.  For the first session, we’ll be discussing chapters 1 and 2 as well as any issues for downloading and configuring your Haskell environment.

    For those who wish to participate, we’ll be using IRC, DimDim and among other technologies to discuss the book.  Stay tuned to the Google Group for more details as they become available.  I have partnered with the Northern Virginia Languages Group (novalang) to have a local meeting as well during this time with the details below:

    Location:
    1818 Library St
    Reston, VA
    View Map

     

    Even before the first meeting, there has been a bit of traffic discussing the book and we’re up to 278 members already!  The response to this book has been amazing and beyond my expectations.  What's also great about this group is that Bryan O'SullivanDon Stewart and John Goerzen, three of the book's authors will also be participating as well.  Hope to have some of you join in the conversation to get a better understanding about both the language, but also functional programming in general.

     

     

     

  • Functional Programming Unit Testing - Part 5

    In the last installment in this series, we talked about code coverage, what they are, and how you should use them.  I gave examples in both Haskell and F# to accomplish this goal.  One thing we've touched briefly in this conversation is around refactoring and cleaning up our code, and it’s about time we come back to that subject.

    But, before we continue, let's get caught up to where we are today:

     

    Refactoring

    I want to revisit our topic of refactoring that I talked about with my foray into testing with HUnit.  In this post and the next couple of posts, I want to explore three different areas with refactoring including the following:

    • Keeping Things Pure
    • Monadic Isolation for Testing
    • Refactoring with frameworks (HLint, etc)

    In this post, let’s cover keeping things pure and separating the side effecting code from our pure code. 

     

    Keeping Things Pure

    Let’s take a simple example of obtaining three odd numbers from a given stream handle.  Because side effects in Haskell are explicit, we have to be mindful of how we get our input.  This affects the signature of our function as it is no longer returning an integer list, but instead an IO integer list.  As I’ve stated in previous posts, you use QuickCheck for your pure code and xUnit frameworks for those with side effects, so in this case, we’d have to write an HUnit test for this function.  Let’s define the unit test which might satisfy those needs now.

    -- RefactoringPure.hs
    module RefactoringPure where

    import System.IO
    import Test.HUnit

    test_getOddList :: Test
    test_getOddList =
      TestCase $ do 
            inh <- openFile "test_getoddlist.txt" ReadMode
            results <- getOddList inh
            assertEqual "test should have three odds" [1,3,5] results

    Then when we’re satisfied with writing this test, we then move onto the actual implementation in order to get this test to pass.  This involves some IO work as we noted before in order to take a given Handle and extract the results line by line.

    -- RefactoringPure.hs
    module RefactoringPure where

    import System.IO

    getOddList :: Handle -> IO [Int]    
    getOddList h = find 3 where
         find 0 = return []
         find x = do
           ln <- hGetLine h
           let ln' = read ln::Int
           if odd ln' then do
                 tl <- find (x - 1)
                 return (ln' : tl) else
               find x
     

    We can then verify our test using the GHCi by using the following to verify the results:

    ghci> runTestTT $ TestList [test_getOddList]
    Cases: 1  Tried: 1  Errors: 0  Failures: 0
    Counts {cases = 1, tried = 1, errors = 0, failures = 0}

    We get the test to pass, but this isn’t very satisfying.  The code looks enormously imperative, and to test all variations of odd numbers seems a bit daunting.  Dealing with IO issues can also lead to brittle tests and not testing the core domain of our application, our algorithms.  Instead, we’re putting too much effort into the IO part and not enough into where it matters most.  What' I’d prefer to write are QuickCheck property-based tests to define my behavior to cover all the variations of input to ensure the behavior of my functions. 

    We need to untangle the pure code from the side effecting code.  We can rewrite the side effecting IO code to be just a simple thin layer on top of our algorithm.  From there, we can tease out the algorithm and write the tests the way they should be written in this situation.

    -- RefactoringPure.hs
    module RefactoringPure where

    import Test.QuickCheck.Batch

    prop_find3Odd_length :: [Int] -> Bool
    prop_find3Odd_length xs =
      length (find3Odd xs) <= 3

    prop_find3Odd_odds :: [Int] -> Bool
    prop_find3Odd_odds =
      all odd . find3Odd
      
    options = TestOptions
      { no_of_tests     = 200,
        length_of_tests = 1,
        debug_tests     = False
      }  
    main :: IO ()  
    main = do
      runTests "find3Odd" options
        [ run prop_find3Odd_length,
          run prop_find3Odd_odds
        ]
     

    I’m much more satisfied with these property-based type checks instead, because they are less brittle and I’m now really testing the core logic of my domain.  The IO code is now nowhere to be found in these tests.  Now, let’s redo the functionality the way that it should be for this functionality that we want.

    -- RefactoringPure.hs
    module RefactoringPure where

    import Control.Applicative
    import System.IO

    getOddList' :: Handle -> IO [Int]
    getOddList' h = (find3Odd . map read . lines) <$> hGetContents h

    find3Odd :: [Int] -> [Int]
    find3Odd = take 3 . filter odd

    Once the functionality has been implemented, we can now run our main function to determine the results of our property-based tests.

    ghci> main
                     find3Odd : ..                               (400)

    What we’ve been able to accomplish here is to separate the core domain of our application from the IO required to receive the input.  This is an important concept, no matter the paradigm between functional programming, object oriented programming or a hybrid approach of the two. 

    I didn’t mention F# in this conversation as there is no enforced purity to be had, but the concepts still easily apply in this situation.  Below is a simple implementation of the Haskell code from above, in F# while isolating the side effecting code as a thin skin layer over top of our algorithm.

    #light

    namespace CodeBetter.Samples

    module RefactoringPure =
      open FsCheck
      open FsCheckExtensions
      open Xunit 
      
      let odd n = n % 2 <> 0
      
      let find3Odd = List.take 3 << List.filter odd
      
      let getOddList (r:System.IO.StreamReader) =
         (find3Odd << List.map int << String.lines) (r.ReadToEnd())
      
      let prop_find3Odd_length xs =
        List.length (find3Odd xs) <= 3
        
      let prop_find3Odd_odds =
        List.for_all odd << find3Odd
      
      [<Fact>]
      let test_prop_find3Odd_length() =
        check config prop_find3Odd_length
        
      [<Fact>]
      let test_prop_find3Odd_odds() =
        check config prop_find3Odd_odds 

    You may notice there are a few functions that don’t exist in the base F# libraries, and over time, I’ve implemented most of the base Haskell List functions in F# that didn’t already have an F# equivalent such as String.lines, List.take and so on.  I’ll cover what those functions are in a later post, because there are a few too many to mention at this point.  There are issues when going back and forth from strings to lists due to them being Seq<char> instead of char list, but that’s another post as well.

    Back to the Haskell world for just a minute, there are other ways of approaching the problem including abstracting the monads and associated types through type classes so that we’re independent of any concrete implementation, which we’ll cover next time.

     

    Conclusion

    Refactoring is an important part of writing code when considering the Red/Green/Refactor paradigm from TDD.  By abstracting pure code from side effecting code, we can write effective tests using property-based checks using QuickCheck for our pure code, instead of more brittle tests which also include IO interaction.  Techniques that will be enumerated in this series will help write more robust and concise functional programming code.

  • Functional Programming Unit Testing - Part 4

    In our previous installment, we talked about bringing together the traditional xUnit tests and QuickCheck property-based tests together in a single cohesive step.  For this installment, let's talk about test coverage.

    But, before we continue, let's get caught up to where we are today:

     

    Code Coverage

    Code coverage is an important metric used as part of our design process to describe to what degree our source code has been tested.  The code coverage tools inspect the code directly as a form of white box testing of your code.  I believe having a high code coverage percentage is important, although such hard-line stances of 100% path code coverage required is most often unnecessary and is evil.  However, for some applications, such as safety-critical, some form of 100% coverage should be considered.

    What do we consider as part of the criteria when we're calculating code coverage?

    • Function coverage
      All functions in the program called?
    • Statement coverage
      All lines in the program called?
    • Branch coverage
      All control structures such as if/then/else evaluated to true and false?
    • Condition coverage
      All boolean sub-expressions evaluated to true and false?
    • Path coverage
      All possible routes through the program called?
    • Entry/exit coverage
      All possible call and return of the function executed?

    Of course some of these are connected in some way such as the following:

    • Decision coverage includes statement coverage since exercising every branch must lead to exercising every statement.
    • Path coverage includes branch coverage.

    Where should we focus?  Using such things as statement coverage, decision coverage, and/or condition/branch coverage, around 80-90% of code coverage would suffice.  Getting to 100% test code coverage is unrealistic and doesn't always ensure quality, and the amount of energy required for this is wasteful. The number we're looking for is somewhere greater than 80%.

    We can use above metrics to determine how well we're writing our tests for our applications.  For many algorithms, it's important to ensure that we have our edge cases covered, especially those in safety-critical systems.  Let's walk through an example in Haskell for code coverage.

     

    Code Coverage with Haskell Program Coverage (HPC)

    The Haskell Program Coverage (HPC) tool is a built-in extension to the Haskell compiler used to record and display the parts of the code that were executed during a run of your program.  With the criteria given above, we are able to record which functions, branches, expressions among other things were evaluated.

    The HPC tool is designed to give you the following metrics:

    • Expressions used (Function coverage)
    • Boolean coverage
      • Guard coverage
      • if confitions
      • Qualifiers
    • Alternatives used
    • Local declarations used
    • Top-level declarations used

    Let's walk through an example of how to use this tool to your advantage.  In the previous post, I've shown some QuickCheck code that doesn't give 100% code coverage so that I can show you how to better achieve it.  Let's look at the example again.

    First, let's look at the implementation of the ROT13 algorithm again:

    --file Encryption.hs
    module Encryption(rot13) where

    import Data.Char

    rot13 :: String -> String 
    rot13 = 
      map mapRot
      where mapRot :: Char -> Char
            mapRot c | c >= 'A' && c <= 'Z' = rot 'A' c
                     | c >= 'a' && c <= 'z' = rot 'a' c
                     | otherwise            = c
            rot :: Char -> Char -> Char 
            rot b c = chr $ (ord c - ord b + 13) `mod` 26 + ord b
     

    Now, let's look at our QuickCheck property-based tests to perform to ensure the correctness of our algorithm. 

    -- file EncryptionTests.hs
    import Data.Char
    import Data.List
    import Encryption
    import Test.Framework
    import Test.Framework.Providers.QuickCheck
    import Test.QuickCheck

    instance Arbitrary Char where
      arbitrary   = elements (['A'..'Z'] ++ ['a'..'z'])

    -- Equal
    prop_rot13_equals s = 
      rot13 s == rot13 s

    -- Single is inequal to original
    prop_rot13_single_notEquals s = 
      rot13 s /= s

    -- Double is equal to original          
    prop_rot13_double_equals s =   
      (rot13 . rot13) s == s

    -- Distribution shapes should be equal  
    prop_rot13_group_equals s = 
      getDistro s == getDistro (rot13 s)
      where getDistro = sort . map length . group . sort

    tests = [
      testGroup "ROT13 Tests" [
        testProperty "prop_rot13_equals" prop_rot13_equals,
        testProperty "prop_rot13_single_notEquals" prop_rot13_single_notEquals,
        testProperty "prop_rot13_double_equals" prop_rot13_double_equals,
        testProperty "prop_rot13_group_equals" prop_rot13_group_equals]
    ]
        
    main = defaultMain tests
     

    In order for us to capture the test coverage data from HPC, we need to add the -fhpc flag to the command-line for compiling our tests such as this:

    >ghc -fhpc EncryptionTests.hs --make

    After instrumenting the code, we then run our code in order to capture the results.  You may have noticed that it created a .hpc folder with a .mix file.  When we run our code, we get the following results as usual.

    >EncryptionTests
    ROT13 Tests:
      prop_rot13_equals: [OK, passed 100 tests]
      prop_rot13_single_notEquals: [OK, passed 100 tests]
      prop_rot13_double_equals: [OK, passed 100 tests]
      prop_rot13_group_equals: [OK, passed 100 tests]

             Properties  Total
    Passed  4           4
    Failed  0           0
    Total   4           4

     

    You will also note that it created a .tix file which captures the actual code coverage metrics.  Let's now analyze the results of our run:

    >hpc report encryptiontests
    97% expressions used (95/97)
    33% boolean coverage (1/3)
          33% guards (1/3), 1 always True, 1 unevaluated
         100% 'if' conditions (0/0)
         100% qualifiers (0/0)
    66% alternatives used (2/3)
    100% local declarations used (3/3)
    100% top-level declarations used (8/8)

    Analyzing the results, we realize we've made a mistake.  If you look back at our Arbitrary Char instance, we're only using alphabetic characters.  The problem arises is that we're not testing a portion of our rot13 function which takes a character that isn't alphabetic.  But, when we change this, we have to be mindful that our tests will have to change as well.  Why?  Because the inequality check will not be successful if there are not letters involved.  Let's make some changes and then check the results again.

    instance Arbitrary Char where
      arbitrary   = elements (['A'..'Z'] ++ ['a'..'z'] ++ "!@#$%^&*()" )

    -- Single is inequal to original
    prop_rot13_single_notEquals s =
      any isAlpha s ==> rot13 s /= s

    Now we can recompile our code once again as we did above and do the run once more.

    >hpc report encryptiontests
    100% expressions used (99/99)
    66% boolean coverage (2/3)
          66% guards (2/3), 1 always True
         100% 'if' conditions (0/0)
         100% qualifiers (0/0)
    100% alternatives used (3/3)
    100% local declarations used (3/3)
    100% top-level declarations used (8/8)

    Much better!  Now we have 100% coverage on our ROT13 implementation.  We also have the ability to dig deeper into the analysis through the use of the markup command.  This will generate web pages which contain drill-down information about our code metrics.   Below is a sample screen shot of my final results of my last run.

    hpc_markup

    This tool is quite powerful for the code analysis we need to ensure that we're writing the right kind of tests for our specifications and implementations.  Now, let's turn our attention to the F# world.  What options do we have?

     

    Code Coverage with TestDriven.NET and NCover

    Once again, the TestDriven.NET addition to F# saves us once again when it comes to code coverage.  With the integration of NCover, we have the ability to perform rather rich analytics on our code much like above using HPC.  Let's take the code from the previous post and look at the relevant parts.

    #light

    namespace CodeBetter.Samples

    module EncryptionTests =
      open System 
      open FsCheck
      open FsCheck.Generator
      open Xunit

      open Encryption
      open ListExtensions
      open FsCheckExtensions

      type CharGenerator =
        static member Chars = 
          elements(['A'..'Z']
                   ['a'..'z'])
      
      overwriteGenerators (typeof<CharGenerator>)
      
      let prop_rot13_equals s =
        propl (rot13 s = rot13 s)

      [<Fact>]
      let test_prop_rot13_equals() =  
        check config prop_rot13_equals

      let prop_rot13_double_equals s =
        propl ((rot13 >> rot13) s = s)

      [<Fact>]
      let test_prop_rot13_double_equals() =  
        check config prop_rot13_double_equals
        
      let prop_rot13_single_notEquals s =
        propl (rot13 s <> s)
      
      [<Fact>]
      let test_prop_rot13_single_notEquals() =  
        check config prop_rot13_single_notEquals
      
      let prop_rot13_group_equals s =
        let getDistro = ListExtensions.defaultSort >> 
                        ListExtensions.group >> 
                        List.map List.length >> 
                        ListExtensions.defaultSort
        propl (getDistro s = getDistro (rot13 s))
        
      [<Fact>]
      let test_prop_rot13_group_equals() =  
        check config prop_rot13_group_equals
     

    In order to get the code metrics we need, simply right-click on the project and click Test With => Coverage.  This will bring up NCover explorer.  We can then browse our results to once again see our mistake.

    ncover_failed

    Now that we realize our mistake of not including normal characters, let's make two changes.  First, let's remove the char generator because the default should suffice.  Unlike the Haskell version, FsCheck comes with an arbitrary char instance already created.  Also, let's ensure the success of the prop_rot13_single_notEquals function by ensuring that it contains at least one letter such as the following:

      let prop_rot13_single_notEquals s =
        List.exists Char.IsLetter s ==> 
          propl (rot13 s <> s)

    This ensures that if we have at least one letter, we can ensure that the ROT13 transformation will make sure the two strings are not equal.  We can now prove our success by once again running the Test With => Coverage option and see the results as below.

    ncover_success

     

    Conclusion

    Tools such as NCover and the Haskell Program Coverage tool, it can ensure our honesty when it comes to tests, and we get a glaring reminder when we don't.  These tools, when combined with our traditional xUnit and property-based tests with saturation test generation can be a satisfying experience.  We've now covered the creation and combination of traditional xUnit tests with property-based tests and how to leverage code coverage as a tool for refining.  There is still more to be covered in this series which includes refactoring. 

  • Functional Programming Unit Testing - Part 3

    In the previous post, we talked about using QuickCheck as opposed to traditional xUnit framework testing.  This covered some of the arguments for using property-based testing for our pure algorithms and relegating the xUnit framework tests for the rest.  The question then arises, how do we tie it all together?

    But, before we continue, let's get caught up to where we are today:

     

    Integrating QuickCheck and xUnit frameworks

    From the previous posts, we've talked about running the xUnit framework code and then running our QuickCheck property checks and both using separate frameworks.  My goal is to break down that barrier so that I can have this as part of a continuous integration and be able to run all of my tests at once and have an easy to use mechanism for determining success or failure.

    In the Haskell world, how might we do this?

     

    Integration HUnit and QuickCheck with Test-Framework

    In Haskell, we have two separate frameworks for testing, a traditional xUnit framework in HUnit and a property based testing framework in QuickCheck.   Luckily, there is a framework out there to integrate the two of them together in a rather seamless manner called Test-Framework.  With this tool, we can group our tests together into a list or two, depending on how you want them grouped.  For example, I could take these following four QuickCheck and one HUnit tests together.

    -- Equal
    prop_rot13_equals s =
      not (null s) ==> rot13 s == rot13 s

    -- Single is inequal to original
    prop_rot13_single_notEquals s =
      not (null s) ==> rot13 s /= s

    -- Double is equal to original          
    prop_rot13_double_equals s =  
      not (null s) ==> (rot13 . rot13) s == s

    -- Distribution shapes should be equal  
    prop_rot13_group_equals s =
      not (null s) ==> getDistro s == getDistro (rot13 s)
      where getDistro = sort . map length . group . sort
    -- Empty ROT13 should return empty  
    test_rot13_empty =
      assertEqual "rot13 should be empty" [] (rot13 [])
     

    And then I could use Test-Framework in order to execute these as a group:

    module TestFrameworkTest where

    import Test.Framework
    import Test.Framework.Providers.HUnit
    import Test.Framework.Providers.QuickCheck
    import Encryption

    tests = 
      [
        testGroup "ROT13 Tests" [
          testProperty "prop_rot13_equals" prop_rot13_equals,
          testProperty "prop_rot13_single_notEquals" prop_rot13_single_notEquals,
          testProperty "prop_rot13_double_equals" prop_rot13_double_equals,
          testProperty "prop_rot13_group_equals" prop_rot13_group_equals,
          testCase "test_rot13_empty" test_rot13_empty]
      ]
        
    main = defaultMain tests
     

    We can now run our tests from the GHCi window and see that our five tests pass.

    ROT13 Tests:
      prop_rot13_equals: [OK, passed 100 tests]
      prop_rot13_single_notEquals: [OK, passed 100 tests]
      prop_rot13_double_equals: [OK, passed 100 tests]
      prop_rot13_group_equals: [OK, passed 100 tests]
      test_rot13_empty: [OK]

             Properties  Test Cases  Total
    Passed  4           1           5
    Failed  0           0           0
    Total   4           1           5
     

    As you can see from the above test output, we have a nice way of verifying our results for both our test cases and property-based checks in a cohesive runner.  We can then integrate this into our continuous integration processes for running all of our tests.

    In the F# world, what are my options?

     

    Integrating FsCheck with Xunit.net

    In a post entitled "F# + TestDriven.NET + xUnit.net = WIN", I showed a simple integration with F#, TestDriven.NET and xUnit.net that gives an entire integration story within Visual Studio.  This time, let's take it a step further to include FsCheck, which is an implementation of QuickCheck 1.0 from the Haskell world.  In order to make this happen, we need to create an IRunner interface instance using an object expression, that I talked about here.

    #light

    namespace CodeBetter.Samples

    module FsCheckExtensions =
      open System
      open FsCheck.Runner
      open Xunit
      
      let xUnitRunner = 
        { new IRunner with
            member x.OnArguments(ntest,args,every)
              args |
              List.iter(function
                | :? IDisposable as d -> d.Dispose() 
                | _ -> ())   
            member x.OnFinished(name, result) =
              match result with
              | True data -> 
                  Assert.True(true)
                  data.Stamps 
                  |> Seq.iter (fun x -> printfn "%d - %A" (fst x) (snd x))
              | False (_,args,None) -> 
                  Assert.True(false, sprintf "%s - Falsifiable: %A" name args)
              | False (_,args,Some exc) -> 
                  Assert.True(false
                    sprintf "%s - Falsifiable: %A with exception %O" name args exc)
              | Exhausted data -> 
                  Assert.True(false
                    sprintf "Exhausted after %d tests" (data.NumberOfTests) )
            }
      let config = {quick with runner = xUnitRunner}

    What this allows me to do is integrate the FsCheck runner with xUnit.net.  As you can see, there are several conditions we must handle such as True, False with or without exception, and Exhausted.  Implementing each is rather simple using the Assert.True function and passing in the given arguments.  I think Exhausted and having an inconclusive state is not proper, so I add that as a failure instead.    Other xUnit based frameworks have the Assert.Fail and Assert.Inconclusive and the latter I don't like because you should know what you're testing to know whether it succeeded or not.

    Now that our runner is written, we can then integrate our property-based tests into using xUnit.net with this example.  We'll use our ROT13 implementation again with four tests.  In order to integrate with xUnit.net, we need to call the check function with our given config as we have above, and our property-based test. 

    let prop_rot13_equals s =
      not (List.is_empty s) ==> 
        propl (rot13 s = rot13 s)

    Then we can define the actual test that xUnit.net will execute using a function decorated with a FactAttribute such as the following:

    [<Fact>]
    let test_prop_rot13_equals() =  
      check config prop_rot13_equals
     

    Running that through the TestDriven.NET runner, we'll find that our code does indeed pass with flying colors.  In addition, we could add additional tests that don't use property-based tests to the solution and have them run at the same time such as the following:

    [<Fact>]
    let rot13_emptyList_should_be_empty() =
      Assert.Empty(rot13 [])
      

    Below is the full implementation of the four tests in addition to the startup code required.

    #light

    namespace CodeBetter.Samples

    module EncryptionTests =
      open System 
      open FsCheck
      open FsCheck.Generator
      open Xunit
      // Local imports
      open Encryption
      open ListExtensions
      open FsCheckExtensions

      type CharGenerator() =
        static member Chars = elements(['A'..'Z'] @ ['a'..'z'])
      
      overwriteGenerators (typeof<CharGenerator>)

      let prop_rot13_equals s =
        not (List.is_empty s) ==> 
          propl (rot13 s = rot13 s)

      [<Fact>]
      let test_prop_rot13_equals() =  
        check config prop_rot13_equals

      let prop_rot13_double_equals s =
        not (List.is_empty s) ==> 
          propl ((rot13 >> rot13) s = s)

      [<Fact>]
      let test_prop_rot13_double_equals() =  
        check config prop_rot13_double_equals
        
      let prop_rot13_single_notEquals s =
        not (List.is_empty s) ==> 
          propl (rot13 s <> s)
      
      [<Fact>]
      let test_prop_rot13_single_notEquals() =  
        check config prop_rot13_single_notEquals
      
      let prop_rot13_group_equals s =
        let getDistro = ListExtensions.defaultSort >> 
                        ListExtensions.group >> 
                        List.map List.length >> 
                        ListExtensions.defaultSort
        not (List.is_empty s) ==> 
          propl (getDistro s = getDistro (rot13 s))
        
      [<Fact>]
      let test_prop_rot13_group_equals() =  
        check config prop_rot13_group_equals
        
      [<Fact>]
      let rot13_emptyList_should_be_empty() =
        Assert.Empty(rot13 [])   
     

    When using the runner, we'll notice that all five tests pass in a relatively short order.  It's a very nice integration.  You may notice the ListExtensions module that I'm using in my prop_rot13_group_equals function.  Basically, it's a port of some of the Haskell functions I use often and translated into F#.  Some of these include sort, group, groupBy, span, sort, dropWhile, etc.  I'll cover the full details in another post, but in the mean time, here are the implementations:

    #light

    module ListExtensions =
      open System

      let defaultSort (l:#IComparable list)
        l |> List.sort (fun a b -> a.CompareTo(b))

      let rec span (f:'a -> bool) (l:'a list) =
        match f, l with
        | _, []             -> [], []
        | p, (x::xs' as xs) ->
            let ys, zs = span p xs'
            if p x then x::ys, zs else [], xs

      let rec groupBy (f:'a -> 'a -> bool) (l:'a list) =
        match f, l with
        | _,  []    -> []
        | eq, x::xs ->
            let ys, zs = span (eq x) xs
            (x::ys) :: groupBy eq zs

      let group (l:'a list) = groupBy (=) l
     

    Pretty simple, yet powerful additions to the list implementations, in my opinion.  After implementing this bridge between FsCheck and xUnit.net, we can then build this easily into our CI process.

     

    Conclusion

    In the functional programming world, we have two main ways of testing our code, either through the traditional xUnit tests or the more powerful QuickCheck property-based tests.  Each of these are powerful in their own right, but made more powerful when combined into a single unit.  When combined we have the power of integrating them into our CI process through some of the build/package tools in our tool belt. 

  • Functional Programming Unit Testing - Part 2

    In the previous post, we talked about some of the basics of functional programming unit testing.  That post mostly focused around HUnit, which is a traditional xUnit testing framework.  This time, let's focus on type-based property testing, which is to create specs which assert logical properties about a function, and then to generate data to test in an attempt to falsify these assertions, through the use of a tool called QuickCheck.

    Much like the traditional xUnit frameworks, this tool helps us flush out the specifications of our software through the use of tests.  Unlike the xUnit frameworks, however, this framework allows us to create generators to help flush out our behaviors and capture our edge cases as we look for ways to falsify our tests.  These generators could use either random data or well structured data that you can craft.  Let's dive a little deeper into what that means.

    But, before we continue, let's get caught up to where we are today:

     

    Introducing QuickCheck

    Testing in the functional programming world is important, especially when precision in algorithms leave little room for error.  With the use of QuickCheck, and property-based testing, we are able to write functions that should satisfy universally, with the actual test data to be generated by QuickCheck in such a way that we specify.  This way, we can literally run thousands of variations that would be pretty unreasonable to write by hand, or by using the RowTest from the MbUnit world.  Doing so, we are able to find subtle edge cases that we may not find otherwise.

    Let's first walk through a simple example of how QuickCheck works before we move onto some more interesting ones.  First, let's do a simple check on a reverse statement.  We'll use the standard prop_ notation to mark our property-based tests from here on out.

    prop_RevRev :: [Int] -> Bool
    prop_RevRev xs = (reverse . reverse) xs == xs
     

    What this code does is say that when calling reverse on a given list twice, it should equal the original list, in this case, an integer list.  We can then use a built-in integer generator to give us our input.  Once the property-based test has been written, we can use the GHCi to run our example:

    quickcheck_revrev

    We can then notice that it tried 100 values against our given function and found that there are no errors.  Had I made a mistake in my property-based test, it would have exited prematurely with the data that caused the particular error.  For example, I could be careless about my input and expect always to take 5 items from a list.

    prop_TakeFive :: [Int] -> Bool
    prop_TakeFive xs = (length . take 5) xs == 5
     

    Now, what we did wrong is assume that our lists were always going to be greater than 5 in length, which could be an issue, and QuickCheck easily alerts us to that fact as shown below:

    quickcheck_takefive

    One thing to remember is that creating property-based tests can be hard and we need to be careful how we specify them.  It takes time to refine them and get them right, but luckily the Haskell community is great for learning either through IRC, Haskell-Cafe or other places.

    Let's walk through another example of a ROT13 implementation and perform property-based testing on it.  A ROT13 is a simple cipher which rotates a given letter by 13 places and when applied twice, will undo itself.  The input handles only alphabetic characters and case does matter.  The question is, how do we test something like this?  Let's look at the basic proof for this:

    ROT13(ROT13(x)) = ROT26(x) = x where x is any given text.

    How do I express that in property-based tests?  Well, let's lay out four basic cases with the given input of data from upper and lower case letters only, and then implement each one.

    1. A ROT13 of a given string should equal a ROT13 of the same string
    2. A ROT13 of a given string should not equal the original string
    3. A ROT13 applied twice to the original string should equal the original string
    4. A ROT13 of a given string should have the same distribution shape as the original.  For example, "foo" when sorted and grouped should be ["f", "oo"]  and then mapped to [1,2].  The shape of its translation to "sbb" should follow the same grouping as well of [1,2].

    Now that we've deduced our criteria for success for this algorithm, let's define the property tests.

    module EncryptionTests where
    import Data.List
    import Encryption(rot13)
    -- Equal
    prop_rot13_equals s =
      not (null s) ==> rot13 s == rot13 s

    -- Single is inequal to original
    prop_rot13_single_notEquals s =
      not (null s) ==> rot13 s /= s

    -- Double is equal to original          
    prop_rot13_double_equals s =  
      not (null s) ==> (rot13 . rot13) s == s

    -- Distribution shapes should be equal  
    prop_rot13_group_equals s =
      not (null s) ==> getDistro (rot13 s) == getDistro s 
      where getDistro = sort . map length . group . sort
     

    We need to define now what data we will be giving to the function in order to create the strings for our property tests.  In order to define the data, we need to create an instance of the Arbitrary typeclass.  Below, we'll define the Char version which includes both upper and lower case letters.

    instance Arbitrary Char where 
      arbitrary     = elements (['A'..'Z'] ++ ['a'..'z'])
      coarbitrary n = variant (ord n)
     

    Now that the rules and data are defined, how might we implement the rot13 function?  Remembering that case does matter, we'll have to handle each one differently.  The implementation would look something like the following:

    module Encryption(rot13) where 

    import Data.Char(chr, ord)

    rot13 :: String -> String 
    rot13 = 
        map mapRot
        where mapRot :: Char -> Char
              mapRot c | c >= 'A' && c <= 'Z' = rot 'A' c
                       | c >= 'a' && c <= 'z' = rot 'a' c
                       | otherwise            = c
              rot :: Char -> Char -> Char 
              rot b c = chr $ (ord c - ord b + 13) `mod` 26 + ord b
     

    We can now run our property tests through QuickCheck through the GHCi console, such as the following:

    quickCheck (prop_rot13_group_equals :: String -> Property)

    Then we'll be able to see the results as shown below:

    quickcheck_encryption

    This seems great, but you may be wondering why you would use this.  The answer is simple, for functionally pure algorithmic work in a functional language, use QuickCheck to formulate the specs.  Else, if there are side effects, state or other behaviors that aren't easily captured using QuickCheck, then the traditional xUnit frameworks apply better.  Even still, if having IO in the code, it's best to refactor the code to separate the pure function from the IO interaction.

    As I mentioned in a previous post, there are other versions out there for us to use.  What about the F# world?

     

    QuickCheck in F#?

    Kurt Schelfthout has been working on a port of the Haskell QuickCheck library to F# called FsCheck, now available on CodePlex.  Today, Kurt released version 0.3 of the product which puts it on par with the QuickCheck 1.0 library, which is well short of the version 2.1.0.1 of QuickCheck now available for Haskell.  But, how do I use it?

    Let's look at some simple examples of some of the above code in F# this time to gain a better understanding of how it works in F#.  First, let's do a translation of the simple reverse function as we did above.

    #light

    open FsCheck

    let prop_RevRev (xs:int list) =
      (List.rev >> List.rev) xs = xs
      
    quickCheck prop_RevRev
     

    After running this code, we see that 100 tests pass nicely.  Now, a quick example of doing the ROT13 implementation.  Just one test should suffice to show how it works.

    #light

    open FsCheck
    open FsCheck.Generator

    let rec rot13 = 
      List.map mapRot
    and mapRot = function
      | c when c >= 'A' && c <= 'Z' -> rot 'A' c
      | c when c >= 'a' && c <= 'z' -> rot 'a'
      | c -> c
    and rot b c = char ((int c - int b + 13) % 26 + int b)

    type CharGenerator() =
      static member Chars = elements(['A'..'Z'] @ ['a'..'z'])
      
    overwriteGenerators (typeof<CharGenerator>)

    let prop_rot13_equals s = 
      (rot13 >> rot13) s = s
      
    quickCheck prop_rot13_equals
     

    Once you run the code, you'll find that it passes the 100 tests easily just as it did in the Haskell version.  I hope that the FsCheck project will continue, and I don't see why not.  After all, it's up to the community to pick it up and run with it.  I'd like to see continued work on the test framework plugins such as xUnit.net, MbUnit and NUnit.  That would make a more integrated story, and that's part of the next post to bring it all together.

    There is a lot more to be covered as I've just touched a very small portion of what QuickCheck can do.  There is a lot of good documentation to be read on the subject on the Haskell Wiki as always.

     

    Conclusion

    As always, it's important to stress design and specification of your functional programming code.  With such toolsets as QuickCheck, we can use this to not only flush out our design, but test our code in many ways through generated data, to help ease the edge cases that might not have been found if coding straight by hand.  Learning these techniques are not always easy and careful consideration must be given when crafting these property tests.

    There is still much to cover in this section, which includes extending HUnit, tying our tests together, and code coverage, so stay tuned.

  • Functional Programming Unit Testing - Part 1

    As you noticed from my last post regarding functional programming and unit testing, there is a bit to be discussed.  Important to any programming language is not only the language, but the frameworks and tooling around it, such is the case with functional languages.  Let's focus on the tooling around testing with functional languages. 

    What kind of options do we have?  In the Haskell world just as the F# world, there are several tools at our disposal to do this. 

    • HUnit
      A traditional xUnit testing framework for unit testing.  Analogous to such frameworks as xUnit.net, NUnit and MbUnit in the .NET world.
    • QuickCheck
      A program in which the developer provides a specification of the program, in the form of properties which functions should satisfy, and then tests that the properties hold in a large number of randomly generated cases that QuickCheck provides.  There are many variants of this tool for most functional languages including F# (FsCheck), Erlang, Scala, Java, Python, Standard ML and others.

    Today we're going to focus on HUnit as part of developing an API in Haskell.  Some of these lessons apply well to any functional language, but is told well using Haskell.

     

    Starting with HUnit

    HUnit is a fairly simple and yet easy to use xUnit based testing framework for Haskell.  It's so bare bones in fact that it only has two main assertion functions that people use, assertEqual and assertBool.  The APIs are straight forward and easy to extend.  I'll do that in a subsequent post to get some of the functionality on par with that of say xUnit.net.

    Let's walk through an example of creating an API for performing calculations on a list.  Since I have a background in quantitative methods, I'll start with some of those.  The first function we need to create is the average function.  This function takes a list and calculates an average over them.  In order to do this, let's define a test to set the behavior.

    -- file HUnitTests.hs
    module HUnitTests (main) where 

    import Test.HUnit
    import HUnitExample(average)

    averageExpected :: Test 
    averageExpected =  
      TestCase (assertEqual "Should get Just averaged number from list" x (average xs)) 
      where xs = [1,2,3
            x  = 2.0 
        
    main :: IO Counts 
    main =  
        runTestTT $ TestList [averageExpected]

    Now that we've defined our criteria for success, now, let's turn our attention to implementing this function.

    -- file HUnitExample.hs
    module HUnitExample (average) where 

    import Data.List

    average :: (Fractional a) => [ a ] -> a 
    average xs = (sum l) / fromIntegral (length xs)

    When running this test from the GHC Interactive (ghci.exe), I get the following results.

    hunit_test

    But, wait!  What happens when we pass an empty list.  That would cause an error due to a divide by zero exception.  What we need to do is add another pattern to our average function to trap that and report a standard error.  Let's define a test case for that.

    -- file HUnitTests.hs
    module HUnitTests (main) where

    import Test.HUnit
    import HUnitExample(average)

    averageExpected :: Test
    averageExpected =  
      TestCase (assertEqual "Should average number from list" x (average xs)) 
      where xs = [1,2,3] 
            x  = 2.0 

    averageEmpty :: Test
    averageEmpty =
      TestCase $ do
        handleJust errorCalls (\_ -> return ()) performCall where
          performCall = do
            evaluate ( average [] )
            assertFailure "average [] must throw an error"

    main :: IO Counts 
    main =  
        runTestTT $ TestList [averageExpected, averageEmpty]
     

    Now to define that failure pattern in my average function.  My test will already succeed because I'm not checking whether it is a divide by zero exception or something else, and I could filter that exception, but I'll do that in another post.

    -- file HUnitExample.hs
    module HUnitExample (average) where

    import Data.List

    average :: (Fractional a) => [ a ] -> a 
    average _  = error "empty list"
    average xs = (sum xs) / fromIntegral (length xs)
     

    Running our tests again, we find that both of them now pass.  Thinking to myself, I think I can generalize this a little bit.  Say for example, I have a list of tuples or record types.  I can't average them exactly as is, but instead, would have to provide a way to extract that value that I do care about.  Let's define a test for that to take a list of tuples and grab the second value and average that one.  I'll omit the rest of the file as it stays the same except for adding our test function to the main function's test list.

    averageByExpected :: Test
    averageByExpected = 
      TestCase $ assertEqual
        "Should get averaged number from a list of tuples" x (averageBy f xs)
      where xs = [("One", 1), ("Two", 2), ("Three", 3)] 
            x  = 2.0 
            f  = (\x -> snd x)
     

    Now the code to implement this should be rather straight forward.  I'll omit the rest of the file and just concentrate on the new averageBy function.

    averageBy :: (Fractional b) => (a -> b) -> [ a ] -> b
    averageBy f xs = (sum . map f) xs / fromIntegral  (length xs)
     

    Instead of using the standard sum, I need to add a map projection to this.  This allows me to add my own custom function to the mix.  Once we get this code implemented, another test then suddenly passes.  But once again, we forgot about the empty l