Sunday, 1. March 2009
Mar 01
In my last article I showed two ways to use parameterized scenarios in NaturalSpec. This time I will show how we can combine both to test a small Quicksort function.
First of all we define a scenario for sorting:
/// predefined sorting scenario
let sortingScenario f list =
Given list
|> When sorting_with f
|> It should be sorted
|> It should contain_all_elements_from list
|> It should contain_no_other_elements_than list
/// predefined Quicksort scenario
let quicksortScenario list = sortingScenario QuickSort list
Now we define some concrete test cases:
[<Scenario>]
let When_sorting_empty_list() =
quicksortScenario []
|> Verify
[<Scenario>]
let When_sorting_small_list() =
quicksortScenario [2;1;8;15;5;22]
|> Verify
[<ScenarioTemplate(100)>]
[<ScenarioTemplate(1000)>]
[<ScenarioTemplate(2500)>]
let When_sorting_ordered_list n =
quicksortScenario [1..n]
|> Verify
[<ScenarioTemplate(100)>]
[<ScenarioTemplate(1000)>]
[<ScenarioTemplate(2500)>]
let When_sorting_random_list n =
quicksortScenario (list_of_random_ints n)
|> Verify
After we defined our spec the task is now to implement the sorting function. I am using a very short (and very naïve) Quicksort implementation in F#:
/// naive implementation of QuickSort - don't use it
let rec quicksort = function
| [] -> []
| pivot :: rest ->
let small,big = List.partition ((>) pivot) rest
quicksort small @ [pivot] @ quicksort big
let QuickSort x =
printMethod ""
quicksort x
If we run the scenario, we get the following output (I shortened a bit):
Scenario: When sorting empty list
– Given []
– When sorting with QuickSort
=> It should be sorted
=> It should contain all elements from []
=> It should contain no other elements than []
==> Result is: []
==> OK
==> Time: 0.0355s
Scenario: When sorting small list
– Given [2; 1; 8; 15; 5; 22]
– When sorting with QuickSort
=> It should be sorted
=> It should contain all elements from [2; 1; 8; 15; 5; 22]
=> It should contain no other elements than [2; 1; 8; 15; 5; 22]
==> Result is: [1; 2; 5; 8; 15; 22]
==> OK
==> Time: 0.0065s
Scenario: When sorting ordered list
[…] 100 elements
==> OK
==> Time: 0.0939s
Scenario: When sorting ordered list
[…] 1000 elements
==> OK
==> Time: 0.7130s
Scenario: When sorting ordered list
[…] 2500 elements
==> OK
==> Time: 3.0631s
Scenario: When sorting random list
[…] 100 elements
==> OK
==> Time: 0.0485s
Scenario: When sorting random list
[…] 1000 elements
==> OK
==> Time: 0.1878s
Scenario: When sorting random list
[…] 1000 elements
==> OK
==> Time: 0.8713s
As you can see the function is much faster if we sort a random list. This is because of the naïve choice of the pivot element.
I don’t want to give better implementations here (use LINQ or PLINQ). I just wanted to show how we can easily verify a test function with NaturalSpec.
Tags:
F#,
NaturalSpec,
quicksort
Saturday, 28. February 2009
Feb 28
I wrote a lot about NaturalSpec in my last articles. This time I will show how we can use parameterized scenarios.
1. Using predefined scenarios
By writing predefined parameterized scenarios we can easily create a scenario suite with lots of different test cases:
// predefined scenario
let factorialScenario x result =
Given x
|> When calculating factorial
|> It should equal result
[<Scenario>]
let When_calculation_factorial_of_1() =
factorialScenario 1 1
|> Verify
[<Scenario>]
let When_calculation_factorial_of_10() =
factorialScenario 10 3628800
|> Verify
If we run these scenarios with NUnit we will get the following output:
Scenario: When calculation factorial of 1
– Given 1
– When calculating factorial
=> It should equal 1
==> OK
==> Time: 0.0093s
Scenario: When calculation factorial of 10
– Given 10
– When calculating factorial
=> It should equal 3628800
==> OK
==> Time: 0.0018s
2. Using the ScenarioTemplate attribute
The second and shorter option is to use the ScenarioTemplate attribute, which is inherited from NUnit’s new TestCase attribute:
// with ScenarioTemplate Attribute
[<ScenarioTemplate(1, 1)>]
[<ScenarioTemplate(2, 2)>]
[<ScenarioTemplate(5, 120)>]
[<ScenarioTemplate(10, 3628800)>]
let When_calculating_fac_(x,result) =
Given x
|> When calculating factorial
|> It should equal result
|> Verify
This code will create 4 different scenarios, which NUnit will display and report separately:

3. Using ScenarioSource
The third option is to use the ScenarioSource attribute. Here we define a function which generates TestData:
/// with a scenario source
let MyTestCases =
TestWith 12 3 4
|> And 12 4 3
|> And 12 6 2
|> And 1200 40 30
|> And 0 0 0 |> ShouldFailWith (typeof<System.DivideByZeroException>)
And then we have to tell NaturalSpec which TestData a scenario should use:
[<Scenario>]
[<ScenarioSource "MyTestCases">]
let When_dividing a b result =
Given a
|> When dividing_by b
|> It should equal result
|> Verify
Summary
Sometime it makes sense to test a scenario with a bunch of different parameters. We can use the ScenarioTemplate attribute to easily parameterize our scenarios. If we want more flexibility we can use predefined scenarios with custom parameters or the ScenarioSource attribute.
Tags:
F#,
NaturalSpec,
nunit,
ScenarioTemplate,
TDD
Wednesday, 25. February 2009
Feb 25
In my last articles I gave an introduction in NaturalSpec, showed how to get started and demonstrated how we can use NaturalSpec to write automatically testable scenarios for C# projects. This time I will use the same “Car-Dealer”-sample to show how we can mock objects in NaturalSpec.
Mocking objects is an important technique in Test-driven development (TDD) and allows us to simulate complex behavior.
“If an object has any of the following characteristics, it may be useful to use a mock object in its place:
- supplies non-deterministic results (e.g. the current time or the current temperature);
- has states that are difficult to create or reproduce (e.g. a network error);
- is slow (e.g. a complete database, which would have to be initialized before the test);
- does not yet exist or may change behavior;
- would have to include information and methods exclusively for testing purposes (and not for its actual task).”
Wikipedia
In our sample we want to mock the Dealer.SellCar() functionality. The first step is to create an C#-Interface for the Dealer:
namespace CarSellingLib
{
public interface IDealer
{
Car SellCar(int amount);
}
}
NaturalSpec is using Rhino.Mocks as the underlying mocking framework, so we have to create a reference to Rhino.Mocks.dll in our spec library.
Now we can modify our spec to:
// 1. open module
module CarSpec
// 2. open NaturalSpec-Namespace
open NaturalSpec
// 3. open project namespace
open CarSellingLib
// define reusable values
let DreamCar = new Car(CarType.BMW, 200)
let LameCar = new Car(CarType.Fiat, 45)
// 4. define a mock object and give it a name
let Bert = mock<IDealer> "Bert"
// 5. create a method in BDD-style
let selling_a_car_for amount (dealer:IDealer) =
printMethod amount
dealer.SellCar amount
// 6. create a scenario
[<Scenario>]
let When_selling_a_car_for_30000_it_should_equal_the_DreamCar_mocked() =
As Bert
|> Mock Bert.SellCar 30000 DreamCar // 7. register mocked call
|> When selling_a_car_for 30000
|> It should equal DreamCar
|> It shouldn't equal LameCar
|> Verify
As you can see we changed part 4 (in order to get a mocked IDealer instead of the concrete Dealer). In part 7 we register our mocked behavior. We want that whenever Bert.SellCar is called with parameter 30000 the DreamCar should be returned.
The Verify-function checks if the mocked function has been called. If not the scenario will fail.
If we verify our spec with a NUnit runner we get the following output:
Scenario: When selling a car for 30000 it should equal the DreamCar mocked
– As Bert
– With Mocking
– When selling a car for 30000
=> It should equal BMW (200 HP)
=> It should not equal Fiat (45 HP)
==> OK
Tags:
F#,
Mocking,
NaturalSpec,
Rhino.Mocks
Monday, 23. February 2009
Feb 23
In my last two articles I gave an introduction in NaturalSpec and showed how to get started. This time I will show how we can use NaturalSpec to write automatically testable scenarios for C# projects.
Like the TDD principle “Write the tests first” we should write our spec first and use the “Red-Green-Refactor” method.
"Red" – Create a spec scenario that fails
At first I created a F# class library project called “Spec.CarSelling” and added project references to NaturalSpec.dll and nunit.framework.dll (see “Getting started” for further explanations).
Now I can write my first scenario:
// 1. define the module
module CarSpec
// 2. open the NaturalSpec namespace
open NaturalSpec
// 3. open project namespace
open CarSellingLib
// 4. define a test context
let Bert = new Dealer("Bert")
// 5. create a method in BDD-style
let selling_a_car_for amount (dealer:Dealer) =
printMethod amount
dealer.SellCar amount
// 6. create a scenario
[<Scenario>]
let When_selling_a_car_for_30000_it_should_equal_my_DreamCar() =
As Bert
|> When selling_a_car_for 30000
|> It should equal (new Car(CarType.BMW, 200))
|> Verify
At this stage the scenario is ready but doesn’t compile. This means we are ready with the "Red"-stage.
"Green" – Make the test the pass
In order to get the test green we have to create a C# class library called CarSellingLib and define the enum CarType and the classes Dealer and Car. Sticking to the YAGNI-principle we implement only the minimum to get the spec green (and ToString()-members for the output functionality).
namespace CarSellingLib
{
public enum CarType
{
BMW
}
}
namespace CarSellingLib
{
public class Car
{
public Car(CarType type, int horsePower)
{
Type = type;
HorsePower = horsePower;
}
public CarType Type { get; set; }
public int HorsePower { get; set; }
public override string ToString()
{
return string.Format("{0} ({1} HP)", Type, HorsePower);
}
public override bool Equals(object obj)
{
var y = obj as Car;
if(y == null) return false;
return Type == y.Type && HorsePower == y.HorsePower;
}
}
}
using System;
namespace CarSellingLib
{
public class Dealer
{
public Dealer(string name)
{
Name = name;
}
public string Name { get; set; }
public Car SellCar(int amount)
{
return new Car(CarType.BMW, 200);
}
public override string ToString()
{
return Name;
}
}
}
When we add a project reference to our spec-project the UnitTests should pass and we have completed the "Green" step. (See "Getting started" if you don’t know how to run the spec.) Now we can add some more scenarios to our spec:
// 1. define the module
module CarSpec
// 2. open NaturalSpec-Namespace
open NaturalSpec
// 3. open project namespace
open CarSellingLib
// 4. define a test context
let Bert = new Dealer("Bert")
// define reusable values
let DreamCar = new Car(CarType.BMW, 200)
let LameCar = new Car(CarType.Fiat, 45)
// 5. create a method in BDD-style
let selling_a_car_for amount (dealer:Dealer) =
printMethod amount
dealer.SellCar amount
// 6. create a scenario
[<Scenario>]
let When_selling_a_car_for_30000_it_should_equal_the_DreamCar() =
As Bert
|> When selling_a_car_for 30000
|> It should equal DreamCar
|> It shouldn't equal LameCar
|> Verify
[<Scenario>]
let When_selling_a_car_for_19000_it_should_equal_the_LameCar() =
As Bert
|> When selling_a_car_for 19000
|> It should equal LameCar
|> It shouldn't equal DreamCar
|> Verify
// create a scenario that expects an error
[<Scenario>]
[<Fails_with "Need more money">]
let When_selling_a_car_for_1000_it_should_fail_with_Need_More_Money() =
As Bert
|> When selling_a_car_for 1000
|> Verify
Now we are in the “Red”-Phase again.
"Refactor" – rearrange your code to eliminate duplication and follow patterns
After making the spec "Green" and doing some refactoring the project code could look like this:
namespace CarSellingLib
{
public enum CarType
{
Fiat,
BMW
}
}
namespace CarSellingLib
{
public class Car
{
public Car(CarType type, int horsePower)
{
Type = type;
HorsePower = horsePower;
}
public CarType Type { get; set; }
public int HorsePower { get; set; }
# region ToString, Equals
public override string ToString()
{
return string.Format("{0} ({1} HP)", Type, HorsePower);
}
public override bool Equals(object obj)
{
var y = obj as Car;
if(y == null) return false;
return Type == y.Type && HorsePower == y.HorsePower;
}
#endregion
}
}
using System;
namespace CarSellingLib
{
public class Dealer
{
public Dealer(string name)
{
Name = name;
}
public string Name { get; set; }
public Car SellCar(int amount)
{
if (amount > 20000)
return new Car(CarType.BMW, 200);
if (amount > 3000)
return new Car(CarType.Fiat, 45);
throw new Exception("Need more money");
}
public override string ToString()
{
return Name;
}
}
}
The spec output should look like the following:
Scenario: When selling a car for 1000 it should fail with Need More Money
– Should fail…
– As Bert
– When selling a car for 1000
Scenario: When selling a car for 19000 it should equal the LameCar
– As Bert
– When selling a car for 19000
=> It should equal Fiat (45 HP)
=> It should not equal BMW (200 HP)
==> OK
Scenario: When selling a car for 30000 it should equal my DreamCar
– As Bert
– When selling a car for 30000
=> It should equal BMW (200 HP)
==> OK
Scenario: When selling a car for 30000 it should equal the DreamCar
– As Bert
– When selling a car for 30000
=> It should equal BMW (200 HP)
=> It should not equal Fiat (45 HP)
>==> OK
4 passed, 0 failed, 0 skipped, took 1,81 seconds (NUnit 2.5).
Summary
I showed how we can use NaturalSpec for the Red-Green-Refactor process of C# projects and how easy it is to get a spec in natural language.
Tags:
.NET,
BDD,
F#,
NaturalSpec,
spec,
TDD
Feb 23
Test-Driven development (TDD) is a well known software development technique and follows the mantra “Red-Green-Refactor”. Behavior-Driven Development (BDD) is a response to TDD and introduces the idea of using natural language to express the Unit Test scenarios.
There are a lot of popular testing frameworks around which can be used for BDD including xUnit.net ,NUnit, StoryQ, MSpec, NSpec and NBehave. Most of them can be used with fluent interfaces and therefore provides a good readability of the sources. Some of them even provide the possibility to generate a spec in natural language out of passed Unit tests.
What is a spec?
“A specification is an explicit set of requirements to be satisfied by a material, product, or service.”
American Society for Testing and Materials (ASTM) definition
A spec is an important document for the communication process – it enables domain experts to communicate with developers. But how can you verify the compliance with the spec? The answer is: you have to write unit tests. Even with the mentioned frameworks there is a lot of work to do in order to translate a spec scenario into a Unit Test.
Question 7 in the famous Joel Test is “Do you have a spec?”.
The idea of NaturalSpec is to give domain experts the possibility to express their scenarios directly in compilable Unit Test scenarios by using a Domain-specific language (DSL) for Unit Tests. NaturalSpec is completely written in F# – but you don’t have to learn F# to use it. You don’t even have to learn programming at all.
Example 1 – Specifying a list
Let’s consider a small example. If we want to test a new List implementation a spec could look like this:
[<Scenario>]
let When_removing_an_3_from_a_small_list_it_should_not_contain_3() =
Given [1;2;3;4;5] // “Arrange” test context
|> When removing 3 // “Act”
|> It shouldn't contain 3 // “Assert”
|> It should contain 4 // another assertion
|> Verify // Verify scenario
I used BDD style here and expressed my scenario in a quite natural language. As the comments are indicating the scenario is following the Arrange Act Assert (“AAA”) pattern.
With the Keyword “Given” I can create a test context (the objects I want to test). In this sample I created a list with 5 elements. With the keyword “When” I call a function which does something with my test context. In this case I want to remove the value 3. In the Assert section (keywords “It should” or “It shouldn’t”) I can give some observations, which should hold for my manipulated test context.
When I run this scenario via a NUnit runner (i am using TestDriven.Net) I get the following output:
Scenario: When removing an 3 from a small list it should not contain 3
– Given [1; 2; 3; 4; 5]
– When removing 3
=> It should not contain 3
=> It should contain 4
==> OK
Example 2 – Specifying a factorial function
If you implement factorial function the spec could look like this:
[<Scenario>]
let When_calculating_fac_5_it_should_equal_120() =
Given 5
|> When calculating factorial
|> It should equal 120
|> Verify
[<Scenario>]
let When_calculating_fac_1_it_should_equal_1() =
Given 1
|> When calculating factorial
|> It should equal 1
|> Verify
[<Scenario>]
let When_calculating_fac_0_it_should_equal_0() =
Given 0
|> When calculating factorial
|> It should equal 1
|> Verify
And the output of NaturalSpec would look like this:
Scenario: When calculating fac 0 it should equal 0
– Given 0
– When calculating factorial
=> It should equal 1
==> OK
Scenario: When calculating fac 1 it should equal 1
– Given 1
– When calculating factorial
=> It should equal 1
==> OK
Scenario: When calculating fac 5 it should equal 120
– Given 5
– When calculating factorial
=> It should equal 120
==> OK
Getting started
Of course you can use NaturalSpec to specify C# objects. I see my post "Using NaturalSpec to create a spec for C# projects" for a small sample.
You can download NaturalSpec at GoogleCode and follow the “Getting started” tutorial in order to write your first automatically testable spec.
I am very interested in your feedback. Do you like the syntax? What should I change? Do you consider using a spec tool like NaturalSpec?
Tags:
BDD,
Behavior-Driven Development,
domain-specific language,
DSL,
F#,
Joel test,
NaturalSpec,
nunit,
spec,
TDD,
Test-Driven Development,
TestDriven.net
Thursday, 29. January 2009
Jan 29
The K-means-Algorithm is one of the simplest unsupervised learning algorithms that solve the well known clustering problem. In this article I will show how we can implement this in F#.
First of all we define an interface for “clusterable” objects:
type IClusterable =
abstract DimValues: float array with get
abstract Dimensions: int
The next step is to define a distance function. We will use n-dimensional Euclidean distance here.

let calcDist (p1:IClusterable) (p2:IClusterable) =
let sq x = x * x
if p1.Dimensions <> p2.Dimensions then
failwith "Cluster dimensions aren’t equal."
p2.DimValues
|> Array.fold2
(fun acc x y -> x – y |> sq |> (+) acc)
0. p1.DimValues
|> sqrt
Now we define a n-dimensional Centroid type. Our kMeans-Algorithm will minimize the squared distances to k centroids (or “means”).
type Centroid =
{Values: float array;
dimensions: int}
member x.Print = printfn "%A" x.Values
interface IClusterable with
member x.DimValues = x.Values
member x.Dimensions = x.dimensions
The centroid of a finite set of n-dimensional points x1, x2, …, xn is calculated as

let calcCentroid (items:’a list when ‘a :> IClusterable)
(oldCentroid:Centroid) =
let count = items.Length
if count = 0 then oldCentroid else
let mValues =
[|for d in 0..oldCentroid.dimensions-1 do
let sum =
items
|> List.sumBy (fun item -> item.DimValues.[d])
yield sum / (count |> float)|]
{ Values = mValues;
dimensions = oldCentroid.dimensions}
We made a small modification – if we don’t have any items assigned to a cluster the centroid won’t change. This is important for the robustness of the algorithm.
Now we can calculate the squared errors to a centroid:
let calcError centroid (items:’a list when ‘a :> IClusterable) =
let calcDiffToCentroid (item:’a) =
centroid.Values
|> Array.fold2
(fun acc c i -> acc + (c-i)*(c-i))
0. item.DimValues
items
|> List.sumBy calcDiffToCentroid
For storing cluster information we create a cluster type:
type Cluster<‘a> when ‘a :> IClusterable =
{Items: ‘a list;
Count: int;
Centroid: Centroid;
Error: float}
member x.Print =
printfn "(Items: %d, Centroid: %A, Error: %.2f)"
x.Count x.Centroid x.Error
static member CreateCluster dimensions (item:’a) =
let items = [item]
let empty =
{ Values = [||];
dimensions = dimensions}
let centroid = calcCentroid items empty
{ Items = items;
Count = 1;
Centroid = centroid;
Error = calcError centroid items}
member x.EvolveCluster (items:’a list) =
let l = items.Length
let centroid = calcCentroid items x.Centroid
{x with
Items = items;
Count = l;
Centroid = centroid;
Error = calcError centroid items}
Now we need a function to initialize the clusters and a function to assign a items to the nearest cluster:
open System
let rand = new Random()
let InitClusters (k:int) dimensions
(items:’a array when ‘a :> IClusterable) =
let length = items.Length
let getInitItem() = items.[rand.Next length]
Array.init k (fun _ ->
getInitItem()
|> Cluster<‘a>.CreateCluster dimensions)
let AssignItemsToClusters k dimensions (clusters:Cluster<‘a> array)
(items:’a seq when ‘a :> IClusterable) =
if k <= 0 then failwith "KMeans needs k > 0"
let findNearestCluster item =
let minDist,nearest,lastPos =
clusters
|> Array.fold
(fun (minDist,nearest,pos) cluster ->
let distance = calcDist item (cluster.Centroid)
if distance < minDist then
(distance,pos,pos+1)
else
(minDist,nearest,pos+1))
(Double.PositiveInfinity,0,0)
nearest
let assigned =
items
|> Seq.map (fun item -> item,findNearestCluster item)
let newClusters = Array.create k []
for item,nearest in assigned do
newClusters.[nearest] <- item::(newClusters.[nearest])
clusters
|> Array.mapi (fun i c -> c.EvolveCluster newClusters.[i])
The last step is a function which calculates the squared error over all clusters:
let calcClusterError (clusters:Cluster<‘a> array) =
clusters
|> Array.sumBy (fun cluster -> cluster.Error)
Now it is an easy task to write the kMeans algorithm:
let kMeansClustering K dimensions epsilon
(items:’a array when ‘a :> IClusterable) =
let k = if K <= 0 then 1 else K
let rec clustering lastError (clusters:Cluster<‘a> array) =
let newClusters =
AssignItemsToClusters k dimensions clusters items
let newError = calcClusterError newClusters
if abs(lastError – newError) > epsilon then
clustering newError newClusters
else
newClusters,newError
InitClusters k dimensions items
|> clustering Double.PositiveInfinity
We can test this algorithm with random 2-dimensional points:
type Point =
{X:float; Y: float}
member x.Print = printfn "(%.2f,%.2f)" x.X x.Y
interface IClusterable with
member x.DimValues = [| x.X; x.Y |]
member x.Dimensions = 2
let point x y = {X = x; Y = y}
let getRandomCoordinate() = rand.NextDouble() – 0.5 |> (*) 10.
let randPoint _ = point (getRandomCoordinate()) (getRandomCoordinate())
let points n = Array.init n randPoint
let items = points 1000
printfn "Items:"
items |> Seq.iter (fun i -> i.Print)
let clusters,error = kMeansClustering 3 2 0.0001 items
printfn "\n"
clusters |> Seq.iter (fun c -> c.Print)
printfn "Error: %A" error
Next time I will show how we can simplify the code by using F#’s built-in type vector instead of array.
Tags:
Centroid,
Clustering,
F#,
k-means,
KMeans
Tuesday, 20. January 2009
Jan 20
Am Freitag dem 29.5.2009 werde ich in Leipzig ein kostenloses “.NET Bootcamp” zum Thema “Funktionale Programmierung in F#” leiten. Die Anmeldung wird ab März auf der Veranstaltungsseite der .NET User Group Leipzig möglich sein.
“Funktionale Programmiersprachen nehmen seit geraumer Zeit einen hohen Stellenwert in der Wissenschaft ein. Demnächst könnte es eine dieser Sprachen sogar aus dem Forschungsbereich direkt in den Mainstream schaffen. Visual Studio 2010 wird neben C# und VB.NET die funktionale Programmiersprache F# als dritte Hauptsprache anbieten. Das .NET Bootcamp zu F# soll einen Einblick in funktionale Konzepte und deren Umsetzung in F# geben. Insbesondere soll auf “Funktionen höherer Ordnung”, Typinferenz, Currying, Pattern Matching, “Unveränderlichkeit” und parallele Programmierung eingegangen werden.”
Veranstaltungsabstract
Update: Die Anmeldung ist nun möglich.
Update: Die Fragen zum BootCamp können nun hier herunter geladen werden.
Tags:
.NET User Group Leipzig,
F#,
F-sharp Bootcamp,
Lernen durch Lehren
Sunday, 11. January 2009
Jan 11
Since I am working with hybrid solutions (with F# and C# projects in it) I had to deactivate ReSharper. ReSharper had a problem with analyzing my F# sources (see JIRA bug entry #79203). The result was that every single F# defined type and function was marked as an error. I nearly got crazy. On one hand I got used to all the nice ReSharper refactorings (and the NUnit runner) and on the other I got all these false positive errors.
But from now on this hard times are over. Today I tested build 1153 (see nightly builds for version 4.5) – and everything works fine.

Thank you guys at JetBrains. 🙂
Tags:
F#,
nunit,
resharper
Jan 11
In the last 3 posts I show how to set up a Continuous Integration environment for F# or C# projects with Subversion (part I), TeamCity (part II) and NUnit (part III).
This time I want to show how we can set up an automated documentation build.
Installing and using GhostDoc
“GhostDoc is a free add-in for Visual Studio that automatically generates XML documentation comments for C#. Either by using existing documentation inherited from base classes or implemented interfaces, or by deducing comments from name and type of e.g. methods, properties or parameters.”
[product website]
GhostDoc is one of my favorite Visual Studio plugins. It allows me to generate comments for nearly all my C# functions. Of course these generated comments aren’t sufficient in every case – but they are a very good start.
Unfortunately GhostDoc doesn’t work for F# 🙁 – the actual version works for C# and the support for VB.Net is called “experimental”.
Download and install http://www.roland-weigelt.de/ghostdoc/.
Now you should be able to generate XML-based comments directly in your C# code:


The next step is to activate the xml-documentation in your Visual Studio build settings:

Commiting these changes and adjusting the build artifacts will produce the input for the documentation build:


Using Sandcastle to generate a documentation
“Sandcastle produces accurate, MSDN style, comprehensive documentation by reflecting over the source assemblies and optionally integrating XML Documentation Comments. Sandcastle has the following key features:
- Works with or without authored comments
- Supports Generics and .NET Framework 2.0
- Sandcastle has 2 main components (MrefBuilder and Build Assembler)
- MrefBuilder generates reflection xml file for Build Assembler
- Build Assembler includes syntax generation, transformation..etc
- Sandcastle is used internally to build .Net Framework documentation”
[Microsoft.com]
Download and install “Sandcastle – Documentation Compiler for Managed Class Libraries” from Mircosoft’s downloadpage or http://www.codeplex.com/Sandcastle.
For .chm generation you also have to install the “HTML Help Workshop“. If you want fancy HTMLHelp 2.x style (like MSDN has) you need “Innovasys HelpStudio Lite” which is part of the Visual Studio 2008 SDK.
“HelpStudio Lite is offered with the Visual Studio SDK as an installed component that integrates with Visual Studio. HelpStudio Lite provides a set of authoring tools you use to author and build Help content, create and manage Help projects, and compile Help files that can be integrated with the Visual Studio Help collection.”
[MSDN]
Last but not least I recommend to install the Sandcastle Help File Builder (SHFB) – this tool gives you a GUI and helps to automate the Sandcastle process.
“Sandcastle, created by Microsoft, is a tool used for creating MSDN-style documentation from .NET assemblies and their associated XML comments files. The current version is the May 2008 release. It is command line based and has no GUI front-end, project management features, or an automated build process like those that you can find in NDoc. The Sandcastle Help File Builder was created to fill in the gaps, provide the missing NDoc-like features that are used most often, and provide graphical and command line based tools to build a help file in an automated fashion.”
[product homepage]
After the installation process start SHFB to generate a documentation project:

Add the TestCITestLib.dll to your project and add nunit.framework.dll as a dependency. Now try to compile your help project – if everything is fine the output should look something like this:

Setting up the documentation build
One of the main principles of Continuous Integration is “Keep the Build Fast” – so I am working with staged builds here. The documentation build should only be started if the first build was successful and all UnitTests are positive. For most projects it is enough to generate the documentation daily or even weekly.
First of all we have to create a simple MSBuild file which executes the SHFB project:
<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- 3rd Party Program Settings -->
<PropertyGroup>
<SandCastleHFBPath>c:\Program Files (x86)\EWSoftware\Sandcastle Help File Builder\</SandCastleHFBPath>
<SandCastleHFBCmd>$(SandCastleHFBPath)SandcastleBuilderConsole.exe</SandCastleHFBCmd>
<SandCastleHFBProject>HelpProject.shfb</SandCastleHFBProject>
</PropertyGroup>
<Target Name="BuildDocumentation">
<!-- Build source code docs -->
<Exec Command="%22$(SandCastleHFBCmd)%22 %22$(SandCastleHFBProject)%22" />
</Target>
</Project>
Add this build file and the SHFB project to your Visual Studio solution folder and commit these changes.

Now we can create a new TeamCity build configuration:

Take the same Version Control Settings like in the first build but use MSBuild as the build runner:

We want the documentation to be generated after a successful main build so we add a “dependency build trigger”:

Now we need the artifacts from the main build as the input for our documentation build:

Be sure you copy the artifacts to the right directory as given in your .shfb-project. Now run the DocumentationBuild – if everything is fine the DocumentationBuild should give you the Documentation.chm as a new artifact:

Tags:
Continuous Integration,
F#,
GhostDoc,
JetBrains,
NDoc,
Sandcastle,
Sandcastle Help File Build,
subversion,
TeamCity,
Visual Studio 2008,
Visual Studio SDK
Thursday, 8. January 2009
Jan 08
In the last two posts I showed how to set up a Subversion (part I: Setting up Source Control) and a TeamCity server (part II: Setting up a Continuous Integration Server).
This time I will show how we can integrate NUnit to run automated test at each build. TeamCity supports all major Testing Frameworks (including MS Test) but I will concentrate on NUnit here.
"NUnit is a unit-testing framework for all .Net languages. Initially ported from JUnit, the current production release, version 2.4, is the fifth major release of this xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities. NUnit brings xUnit to all .NET languages."
[product homepage]
Creating a TestProject
First of all download and install NUnit 2.4.8 (or higher) from http://www.nunit.org/.
Now we add a small function to our F# source code:
let rec factorial = function
| 0 -> 1
| n when n > 0 -> n * factorial (n-1)
| _ -> invalid_arg "Argument not valid"
This is the function we want to test. We add a new C# class library to our solution (e.g. “TestCITestLib” 😉 ) and add a reference to nunit.framework. Inside this new TestLibrary we add a TestClass with the following code:
namespace TestCITestLib
{
using NUnit.Framework;
[TestFixture]
public class FactorialTest
{
[Test]
public void TestFactorial()
{
Assert.AreEqual(1, Program.factorial(0));
Assert.AreEqual(1, Program.factorial(1));
Assert.AreEqual(120, Program.factorial(5));
}
[Test]
public void TestFactorialException()
{
Program.factorial(-1);
}
}
}
To ensure the build runner is able to compile our solution we put the nunit.framework.dll near to our TestProject and commit our changes.

Configure TeamCity for UnitTesting
The next step is to tell TeamCity that the build runner should run our UnitTests:

If we now run the build we should get the following error:

Our second test function failed, because we didn’t expect the System.ArgumentException. We can fix this issue by adding the corresponding attribute to the Testfunction:
[Test,
ExpectedException(typeof(System.ArgumentException))]
public void TestFactorialException()
{
Program.factorial(-1);
}0

Configure the build output
At this point we have a minimalistic Continuous Integration infrastructure. Every time someone performs a Commit on our repository a automated build will be started and the sources will be tested against the given UnitTests. Now we should concentrate on getting our build output – the artifacts. The term artifact is usually used to refer to files or directories produced during a build. Examples of such artifacts are:
- Binaries (*.exe, *.dll)
- Software packages and installers (*.zip, *.msi)
- Documentation files (e.g. help files)
- Reports (test reports, coverage reports, …)
At this time we are only interested in the binaries (this means CITestLib.dll). We can add the following artifact definition to our TeamCity project:

If we now rebuild our solution the build runner collects the configured artifacts and stores them with all build information:

Next time I will show how we can add more artifacts – e.g. an automated documentation.
Tags:
Continuous Integration,
F#,
JetBrains,
MSTest,
nunit,
subversion,
TeamCity,
UnitTest,
UnitTesting,
Visual Studio 2008