Dublin ALT.NET session Thu Oct 24 2013
-
Upload
ruben-bartelink -
Category
Technology
-
view
523 -
download
0
description
Transcript of Dublin ALT.NET session Thu Oct 24 2013
HOW LONG WILL IT TAKE YOU?
@RBARTELINK
DUBLIN ALT.NET
24 OCTOBER, 2013
Testing . NET systems using F#
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
aimOne size won’t fit all
http://martinfowler.com/bliki/TestPyramid.html (originated by Mike Cohn)
ATDD workflow
http://www.infoq.com/articles/atdd-from-the-trenches
Why?
You need to express high and low level testsMbUnit, Sub/N/M/Spec are single paradigm3 year old tests are uglier than 3yo
production codeTest code is just different to production codeLearn a language a yearF# has been in VS since 2009One of F#’s many paradigms is to be a better
C#
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
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
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 @>
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 |
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() @>)
Low Level Stuff
Type inference (for real)
any() It.IsAny<DateTime>()
mock() Mock.Of<T>
Tuples let tuple = key,valuelet _,value = tuple
var tuple = Tuple.Create( key, value)var value = tuple.Item2
Lambdas let gen a b = CreateSut a b |> Filllet 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)var list = mock.Object;
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 projectF12 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…”)
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)
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/outside-in-tdd