Monthly Archives: October 2017

There and Back Property

Coming up with properties can be difficult and require a lot of thought. We need to really understand the code or process we are testing against. Thankfully there are some common patterns that our predecessors have identified to help get us started. We’ll start looking at the there and back property.

There and Back

This is a property we can use to verify anything that sets and gets values. Verify data transfer objects or writing and reading from disk. We can use this property to any process that performs a transform that can be reversed. Serialization and deserialization are a good example of a transformation with a reversal. We can serialize and deserialize the data and confirm we get the exact same data that we put in.

I went searching the internet for a good example to test the there and back property. I ended up on the MSDN website with an encryption/decryption, example. I’ve experienced some pain with an encryption library in the past, so this was perfect. Long story short, we had to use a 3rd party encryption library and 8 months into production we found that every key had a subset of values that would not decrypt.

Encryption Library

I placed the encryption code in a C# library which can be found Property Based Testing – There and Back. The project can be built and there should be a ThereAndBack.dll in the bin/debug directory.

FsCheck

The property based testing library for .Net is FsCheck. The FsCheck library can be downloaded using nuget or paket. We can now reference FsCheck and the ThereAndBack.dll built from the downloaded project.

The function ``Check there and back of DateTime encryption`` is the property we are asserting. The body of the function creates an instance of the Encryption object from the C# library. It then converts the input DateTime to a string, encrypts, decrypts, and parses it back to a DateTime. The result of that process is then compared to the original input DateTime value. This gives us our “There and Back” property.

We execute the function with Check.Quick. FsCheck executes the function 100 times while generating a new DateTime value each time.

Summary

Starting with the “There and Back” property is a good way to get introduced to property based testing. This property can be used for any data transformation that has a means to reverse the data back to its original form. This makes the property good for testing any new serialization library we may be using, or writing. We can also use this property for testing writing and reading from disk to find corruption or hardware errors.

What Is Property Based Testing

I originally looked into property based testing a while ago. I knew that it was something I wanted to come back to and dig deeper. I got my chance and recently gave a talk on it at Prairie Dev Con Deliver. This conference is focused on Agile methodologies and testing.

Property Based Testing

Property based testing differs from unit testing in that it doesn’t use specific inputs and results. It instead uses a property to determine correct behaviour. I looked up the definition of Property in the dictionary and came up with “a trait belonging to a process with results common to all members of a set of inputs.” This is still a little abstract, but I found adding an example helped me understand further.

First Property

Any positive number multiplied by negative one will have a result less than zero. In this example:

  • The process is multiplication with negative one: (*) -1
  • The input set is any positive number: choose {1 .. }
  • The result is a number less than zero: < 0

These three pieces make up the property we are asserting.

Generative Advantage

One of the big advantages to property based testing over normal testing is the generative aspect of it. Property based testing doesn’t rely on specific example based testing. The system generates values based on the specifications required. Since the system is generating values at each run, the tests are always actively looking for defects. This also lets the system come up with many variations of inputs that we humans may not think of. This means we may detect a defect that can occur when given a large set of data.

A nice feature to some testing libraries, such as .Net’s FsCheck, is shrinking. When a falsifiable input is found, Shrinking allows the system to start minimizing (shrinking) the input values required to generate the defect. The idea is to make the inputs be as manageable as possible for the developer to be able to reproduce the error with minimal effort. The ideal use case would be to take that falsifiable example and put it in a unit test.

Like unit tests, we come up with many different properties of the process we are testing. The difficulty with property based testing is coming up with properties can be time consuming and difficult. On the other hand, the time consuming and thought does allow us to gain greater knowledge of the process we are testing. Thankfully though, there are some common patterns that have emerged as good ways to get started. We will look at the There and Back property in the next post.

Summary

Property based testing is a unique way to ensure your code is as defect free as possible. We’ve defined three requirements for a property. The process is what we are testing. The input set or subset required to test the process. In the example above we used any positive number. The results with some defined commonality of evaluating the process on our input set.

Function Pattern Shorthand

Match Shorthand

There is a shorthand for a function that immediately passes the last argument (See Currying and Applying Arguments). We can use this shorthand to rewrite our greeting function to be:

let greeting = function
    | {Name = "Dave"; Year = 2001 } 
        -> "I'm sorry Dave, I'm afraid I can't do that."
    | {Name = "Neil"}
        -> "The first person to set foot on the moon."
    | {Name = name}
        -> sprintf "Hello %s." name

Our shorthand above will still have a type signature of Astronaut -> string. The difference is the argument is implied. Loading the Astronaut type and the shorthand greeting function in Visual Studio Code with Ionide-FSharp you will see a result of val greeting : _arg1:Astronaut -> string. Using the shorthand is a very common practice when your function is immediately doing a pattern match.

This shorthand is a matter of preference by the developer. There are multiple styles to use for a function which goes directly into a pattern match.

If a pattern match has only 2 values, some people prefer to use an if then else block. We can still use a match expression or a function pattern. The functions below have the same result and behaviour. It becomes a matter of readability and preference.

let boolYesNo b = if b then "Yes"
                  else "No"

let boolYesNo' b = 
    match b with
    | true  -> "Yes"
    | false -> "No"

let boolYesNo'' = function
    | true  -> "Yes"
    | false -> "No" 

Summary

Using a Function Pattern Shorthand can remove some overhead of the developer by indicating an immediate match. The function pattern shorthand will immediately match on the last argument supplied to the function. Some prefer to use if then else if a match has only two outcomes. It is the preference of the developer as to which style of matching they will use.