This document discusses using F# for testing .NET systems. It recommends using a test pyramid approach with more acceptance tests (AT) than unit tests (UT). It provides examples of how to write ATs using Gherkin syntax and the TickSpec BDD framework in F#. It also gives examples of unit testing with TickFacts and mocking libraries. The document notes some limitations of mixing F# and C# but recommends F# as a better language for testing due to its support for many paradigms and features useful for testing like tuples, lambdas, and quotations. It concludes with recommendations for books and resources on testing with F# and ATDD.
What's New in Teams Calling, Meetings and Devices March 2024
Dublin ALT.NET session Thu Oct 24 2013
1. Testing . NET systems using F#
HOW LONG WILL IT TAKE YOU?
@RBARTELINK
DUBLIN ALT.NET
24 OCTOBER, 2013
2. The test pyramid
It’s not easy to achieve a good balance in a set of tests
Too much AT -> slow + doesn’t drive implementation properly
Too much UT -> Not meeting Living Documentation aim
One size won’t fit all
http://martinfowler.com/bliki/TestPyramid.html (originated by Mike Cohn)
4. Why?
You need to express high and low level tests
MbUnit, Sub/N/M/Spec are single paradigm
3 year old tests are uglier than 3yo production code
Test code is just different to production code
Learn a language a year
F# has been in VS since 2009
One of F#’s many paradigms is to be a better C#
5. What can I use
Everything (yes, everything) you know
NUnit, MSpec, SpecFlow
FluentAssertions,
RhinoMocks, FakeItEasy, NSubstitute
Things you’re already using
xUnit.net, LINQ, Moq
Modern Libs
AutoFixture, AutoFixture.xUnit, AutoFixture.AutoMoq
Foq, AutoFixture.AutoFoq
TickSpec
6. Gherkin
Feature files (Gherkin)
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario: Add two numbers
When I add 2 and 2
Then I should see 4
7. TickSpec
TickFacts
[<TickFact>] let AdditionFeature () =
EmbeddedResourceFeatures.ScenariosFrom “Addition"
Step Definitions (TickSpec with unquote)
module CalculatorSteps =
[<When>] ``I add (.*) and (.*)`` x y =
result <- Calculator()
|> enter x |> plus |> enter y
|> compute
[<Then>] ``I should see (.*)`` expected =
test <@ expected = result @>
8. Gherkin Backgrounds and Outlines
Feature: Addition
Background:
Given I switch my calculator to fancy mode
Scenario Outline: The Hard Stuff
When I add <First> and <Second>
Then I should see <Total>
Examples:
|First|Second|Total|
|1
|1
|2
|
|9
|-1
|8
|
9. Unit Testing
Tick methods (xUnit/NUnit with unquote)
module CalculatorFacts =
[<Fact>] let ``Adding two small ints works`` () =
let result = Calculator() |> enter 2 |> plus |> enter 2 |> compute
test <@ 2+2 = result @>
Mocking DSLs (Foq)
Mock<IList<char>>.With(fun x ->
<@ x.Count --> 2
x.Item(0) --> '0'
x.Item(1) --> '1'
x.Contains( any() ) --> true
x.RemoveAt( 2) ==> System.ArgumentOutOfRangeException()
@>)
10. Low Level Stuff
Type inference any()
(for real)
It.IsAny<DateTime>()
mock()
Mock.Of<T>
Tuples
let tuple = key,value
let _,value = tuple
var tuple = Tuple.Create( key, value)
var value = tuple.Item2
Lambdas
let gen a b = CreateSut a b |> Fill
let gen = CreateSut >> Fill
var gen = (int a, int b) =>
CreateSut( a, b).Fill()
Object
Expressions
let time = { new ITime with
member mock.GetHour() = 15}
class FakeTime15 {int GetHour() { return
15;}}
var time = new FakeTime15()
Custom ops
expected =? Actual // From unquote
Asset.Equal( expected, actual)
Quotations
test <@ expected =
result |> String.Concat “,” @>
Assert.That( expected, Is.EqualTo(
String.Concat( “,”, result)));
let list = Mock<IList>
.Method(fun x -> <@ x.Contains @>)
.Returns( true)
var mock = new Mock<IList>();
mock.Setup( x=> x
.Contains( It.IsAny<object>())
.Returns( true)
11. The bad points
Need to install FSC on CI server (2 clicks or 11 MB
MSI or put FSC in tools dir Just Works)
You can’t mix F# and C# in a single project
F12 from F# to/from C# doesn’t work (but built in
Ctrl-, and F12 within files is fine)
No refactoring support of consequence (but not as
important as you think)
C# starts to grate a little more every day (as does “in
F# you can just…”)
12. Books
Growing Object Oriented Software, Guided by Tests
(Freeman, Pryce)
Specification By Example (Adzic)
The RSpec book (Chelimsky et al)
Expert F# 3 (Syme)
Real World Functional Programming in F# and C#
(Petricek, Skeet)
13. Resources
F#
@ptrelford http://trelford.com/blog and samples
SO F# tag
Google
@tomaspetricek http://tomasp.net/blog/
Don’t forget MSDN
ATDD
GOOS
@ploeh Outside In Test Driven Development
http://pluralsight.com/training/Courses/TableOfContents/ou
tside-in-tdd