Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save miklund/aa5d6c8597e897d36252 to your computer and use it in GitHub Desktop.
Save miklund/aa5d6c8597e897d36252 to your computer and use it in GitHub Desktop.
2015-06-04 Property-Based Testing with F#
# Property-Based Testing with F#
# Author: Mikael Lundin
# Link: http://blog.mikaellundin.name/2015/06/04/property-based-testing-with-fsharp.html
public static T[] BubbleSort<T>(T[] input) where T : IComparable
{
var result = new T[input.Length];
input.CopyTo(result, 0);
T temp = result[0];
for (int i = 0; i < result.Length; i++)
{
for (int j = i + 1; j < result.Length; j++)
{
if (result[i].CompareTo(result[j]) > 0)
{
temp = result[i];
result[i] = result[j];
result[j] = temp;
}
}
}
return result;
}
public static T[] BubbleSort<T>(T[] input) where T : IComparable
{
if (input.Length == 0)
{
return input;
}
var result = new T[input.Length];
input.CopyTo(result, 0);
T temp = result[0];
for (int i = 0; i < result.Length; i++)
{
for (int j = i + 1; j < result.Length; j++)
{
if (result[i].CompareTo(result[j]) > 0)
{
temp = result[i];
result[i] = result[j];
result[j] = temp;
}
}
}
return result;
}
open FsCheck
open PropertyBasedTesting.CSharp
let ``Sorting the list once is equal to sorting the list twice`` (input : int array) =
ArrayUtils.BubbleSort input = ArrayUtils.BubbleSort(ArrayUtils.BubbleSort input)
open FsCheck.Xunit
open PropertyBasedTesting.CSharp
[<Property>]
let ``Sorting the list once is equal to sorting the list twice`` (input : int array) =
ArrayUtils.BubbleSort input = ArrayUtils.BubbleSort(ArrayUtils.BubbleSort input)
// Check.Quick ``The first item in the sorted list is the smallest``
[<Property>]
let ``The first item in the sorted list is the smallest`` (input : int array) =
(input.Length) > 0 ==>
lazy((ArrayUtils.BubbleSort input).[0] = Seq.min input)
// Check.Quick ``The Last item in the sorted list is the largest``
[<Property>]
let ``The Last item in the sorted list is the largest`` (input : int array) =
(input.Length) > 0 ==>
lazy((ArrayUtils.BubbleSort input).[input.Length - 1] = Seq.max input)
// Check.Quick ``All items from the original list are present in the sorted list``
[<Property>]
let ``All items from the original list are present in the sorted list`` (input : int array) =
let sorted = ArrayUtils.BubbleSort input
(sorted.Length = input.Length)
|@ "same length" .&.
(sorted |> Seq.forall (fun x -> Seq.exists ((=) x) input))
|@ "all elements exists"
// Check.Quick ``The items in the sorted list are ordered``
[<Property>]
let ``The items in the sorted list are ordered`` (input : int array) =
ArrayUtils.BubbleSort input
|> Seq.pairwise |> Seq.forall (fun (a, b) -> a <= b)
public class CommitTransactionShould
{
[Test]
public void SetStatusToCommitted()
{
// AAA
}
}
Feature: Order Checkout
Scenario: Pushing order button gives confirmation with order number
Given an order at the order checkout page
And invoice is selected as payment option
When order button is clicked
Then order confirmation should be displayed
And order number should be visible
public class Rating
{
/// <summary>
/// Send in the user rating
/// </summary>
/// <param name="value">A number 1 - 5</param>
public void Rate(int value)
{
}
/// <summary>
/// Returns the average rating value
/// </summary>
public double Average
{
}
/// <summary>
/// The number of stars to display, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5
/// </summary>
public double Stars
{
}
}
// generate list with values 1-5
type RatingProperties =
// generator
static member ratingValues =
let range = Arb.generate<int> |> Gen.suchThat ((>) 6) |> Gen.suchThat ((<) 0)
Gen.listOf<int> range |> Arb.fromGen
open FsCheck
open PropertyBasedTesting.CSharp
// Arb.registerByType (typeof<RatingProperties>)
// Check.QuickAll (typeof<RatingProperties>)
type RatingProperties =
// generator
static member ratingValues =
let range = Arb.generate<int> |> Gen.suchThat ((>) 6) |> Gen.suchThat ((<) 0)
Gen.listOf<int> range |> Arb.fromGen
// property
static member ``Number of stars should be closest proximity discrete star to the average value`` (input : int list) =
// create sut
let rating = Rating()
// send in ratings
List.iter (fun v -> rating.Rate(v)) input
// trace
printf "Rating: %A\n" rating
// assert
match rating.Stars with
| 0.0 -> rating.Average = 0.0
| 1.0 -> rating.Average < 1.25
| 1.5 -> 1.25 <= rating.Average && rating.Average < 1.75
| 2.0 -> 1.75 <= rating.Average && rating.Average < 2.25
| 2.5 -> 2.25 <= rating.Average && rating.Average < 2.75
| 3.0 -> 2.75 <= rating.Average && rating.Average < 3.25
| 3.5 -> 3.25 <= rating.Average && rating.Average < 3.75
| 4.0 -> 3.75 <= rating.Average && rating.Average < 4.25
| 4.5 -> 4.25 <= rating.Average && rating.Average < 4.75
| 5.0 -> 4.75 <= rating.Average
| x -> false
public class SaveToDatabaseShould
{
[Test]
public void ReturnEntityWithAutoIncrementedID()
{
// AAA
}
}
[Test]
public void ShouldReturnListOfNumberInOrder()
{
// setup
var data = new [] { 1, 13, 5, 8, 2, 3, 1 };
// test
var result = ArrayUtils.BubbleSort(data);
// assert
Assert.That(result, Is.EqualTo(new [] { 1, 1, 2, 3, 5, 8, 13}));
}
public double Stars
{
get
{
return Math.Round(2 * Average, MidpointRounding.AwayFromZero) / 2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment