2010-01-01 13 views
100

Ich habe gerade mit F # angefangen, was meine erste funktionale Sprache ist. Ich habe fast ausschließlich mit C# gearbeitet und genieße es sehr, wie F # mich dazu bringt, zu überdenken, wie ich Code schreibe. Ein Aspekt, den ich etwas verwirrend finde, ist die Veränderung des Code-Schreibens. Ich benutze TDD seit Jahren in C# und schätze es wirklich, Unit-Tests zu haben, um zu wissen, wo ich bin.F # Entwicklung und Komponententests?

Bisher war mein Prozess mit F #, einige Funktionen zu schreiben, mit ihnen mit der interaktiven Konsole zu spielen, bis ich "einigermaßen" sicher bin, dass sie arbeiten, und zwicken & kombinieren. Das funktioniert gut bei kleinen Problemen wie dem Euler-Projekt, aber ich kann mir nicht vorstellen, so etwas Großes zu bauen.

Wie nähern sich Personen dem Testen von Einheiten und erstellen eine Testsuite für ein F # -Programm? Gibt es ein Äquivalent zu TDD? Alle Hinweise oder Gedanken sind willkommen.

+1

http://www.expert-fsharp.com/CodeSamples/Forms/AllItems.aspx?RootFolder=%2fCodeSamples%2fChapter18%2fExample06 zeigt ein einfaches Beispiel # NUnit mit F verwenden. – itowlson

+0

siehe http://stackoverflow.com/questions/1468772/how-to-handle-unit-tests-in-f –

+0

bezogen: http://stackoverflow.com/questions/5667372/what-unit-testing-frameworks- are-available-for-f/5669263 # 5669263 (Unquote ist weit mehr als eine Fußnote/Kommentar wie in der Antwort auf dieser Seite) –

Antwort

71

Testgetriebene Entwickler sollten sich in funktionalen Sprachen wie F # wie zu Hause fühlen: kleine Funktionen, die deterministisch wiederholbare Ergebnisse liefern, eignen sich perfekt für Komponententests. Es gibt auch Fähigkeiten in der Sprache F #, die das Schreiben von Tests erleichtern. Nehmen wir zum Beispiel Object Expressions. Sie können sehr einfach Fälschungen für Funktionen schreiben, die als Eingabe einen Schnittstellentyp verwenden.

Wenn überhaupt, ist F # eine objektorientierte Sprache erster Klasse, und Sie können die gleichen Werkzeuge und Tricks verwenden, die Sie beim Ausführen von TDD in C# verwenden. Es gibt auch einige Tests-Tools geschrieben in oder speziell für F #:

Matthew Podwysocki ein großes series auf Unit-Tests in funktionalen Sprachen geschrieben . Onkel Bob schrieb auch einen zum Nachdenken anregenden Artikel here.

+9

Ich habe auch eine F # spezifische Einheitentestbibliothek namens Unquote entwickelt (und entwickle sie aktiv): http://code.google.com/p/unquote/. Sie können Test-Assertions als einfache, statisch überprüfte F # -Boolesche Ausdrücke mit F # -Ausgaben schreiben und automatisch Testfehlermeldungen erzeugen. Es funktioniert konfigurationsfrei mit spezieller Unterstützung sowohl für xUnit.net als auch für NUnit und unterstützt im Allgemeinen jedes ausnahmebasierte Einheitentestframework. Es funktioniert sogar innerhalb von FSI-Sitzungen, die eine nahtlose Migration von interaktiven Tests zu formellen Testsuiten ermöglichen. –

+0

Es gibt auch [Pex] (http://www.pexforfun.com/), obwohl das ein bisschen schwieriger zu ranken ist. – Benjol

+0

Onkel Bob Link scheint tot – bump

6

Sie könnten einen Blick auf FSUnit werfen - obwohl ich es noch nicht benutzt habe, könnte es einen Versuch wert sein. Sicher besser als zum Beispiel (native) NUnit in F # zu verwenden.

+1

ShdNx, warum würden Sie gegen NUnit empfehlen? Don Symes F # -Buch zeigt NUnit zum Testen und es sieht ziemlich ähnlich aus wie NUnit in C# zu verwenden. Die FSUnit DSL sieht cool aus, aber für Leute, die bereits mit NUnit vertraut sind (Mathias "benutzt TDD seit Jahren") ist es Ihre Erfahrung, dass die Verwendung von NUnit mit F # problematischer ist als mit C# oder VB? – itowlson

+0

Ich zweite Itowlson Kommentar und Frage. Auf jeden Fall sieht NUnit in F # ziemlich seltsam aus, aber abgesehen davon, sind Ihnen bestimmte Probleme bekannt, die es sinnvoll machen, etwas anderes zu verwenden? – Mathias

+1

Ich würde sagen, dass "ziemlich seltsam aussieht" ist in der Regel ein zwingender Grund, etwas besseres zu finden. Ungewöhnlich zu sein bedeutet schwer zu lesen und schwer zu lesen bedeutet Fehler. (Ich gehe davon aus, dass "seltsam aussieht" ist völlig anders als "neu und/oder unbekannt" - ungewohnt wird vertraut, ungerade wird seltsam.) –

10

Ich denke, das ist eine sehr interessante Frage, über die ich mich selbst oft gefragt habe. Meine Gedanken sind bisher nur Gedanken, also nimm sie für das, was sie sind.

Ich denke, dass das Sicherheitsnetz einer automatisierten Testsuite zu wertvoll ist, um loslassen zu können, egal wie verlockend die interaktive Konsole auch sein mag, also plane ich wie immer Unit Tests zu schreiben.

Eine der größten Stärken von .NET sind die sprachübergreifenden Funktionen. Ich weiß, dass ich bald F # -Produktionscode schreiben werde, aber mein Plan ist, Komponententests in C# zu schreiben, um mir den Weg zu einer neuen Sprache zu ebnen. Auf diese Weise kann ich auch testen, dass das, was ich in F # schreibe, mit C# (und anderen .NET-Sprachen) kompatibel ist.

Mit diesem Ansatz verstehe ich, dass es bestimmte Funktionen von F # gibt, die ich nur intern in meinem F # -Code verwenden kann, aber nicht als Teil meiner öffentlichen API aussetzen, aber ich werde das akzeptieren, genauso wie ich das heute akzeptiere Es gibt bestimmte Dinge, die C# mir erlaubt, (wie uint) auszudrücken, die nicht CLS-konform sind, und daher verzichte ich darauf, sie zu verwenden.

+1

Wie war dein Plan? Es war einfach, f # -Code mit C# -Code zu testen? Ich fing an, f # zu lernen und mein Plan ist, einen Teil meines Projekts in f # zu schreiben und ich habe die gleiche Idee: Komponententests auch in C# für f # zu schreiben. –

+0

@Markieren Sie Updates? Es fällt mir auch schwer, mit TD mit F # zu fließen. –

+1

@ScottNimrod Ziemlich ein paar Updates: vier von [meinen Pluralsight-Kursen] (http://bit.ly/ploehralsight) sind über das Testen oder TDD mit F #. Sie finden auch viele kostenlose Aufnahmen von Konferenzvorträgen auf [mein Lanyrd-Profil] (http://lanyrd.com/profile/ploeh).Schließlich gibt es [mein Blog] (http://blog.ploeh.dk). –

14

Werfen Sie einen Blick auf FsCheck, ein automatisches Test-Tool für F #, ist im Grunde ein Port von Haskell's QuickCheck. Es ermöglicht Ihnen, eine Spezifikation von das Programm, in Form von Eigenschaften, die die Funktionen oder Methoden sollten erfüllen, und FsCheck Tests, die die Eigenschaften in einer großen Anzahl von zufällig generierten Fällen halten.

FsCheck CodePlex Page

FsCheck Author Page

+0

Ja, ich denke, FsCheck bietet viel mehr als traditionelle Unit-Test-Frameworks wie NUnit usw. – Robert

21

Ich verwende NUnit, und es gefällt mir nicht so hart treffen zu lesen oder zu beschwerlich schreiben:

open NUnit.Framework 

[<TestFixture>] 
type myFixture() = class 

    [<Test>] 
    member self.myTest() = 
     //test code 

end 

Seit meinem Code eine Mischung aus F # und andere .Net-Sprachen, ich mag die Tatsache, dass ich die Unit-Tests im Grunde die gleiche Art und Weise und mit ähnlicher Syntax in F # und C# schreiben.

+4

Nachdem ich andere Antworten hier gelesen habe, gab ich FSUnit einen Versuch, und ich denke, es ist großartig. Es funktioniert gut mit TestDriven.Net (wie auch NUnit), regt einen fließenden Stil des Schreibens von selbstdokumentierenden Tests an und ist, wie Ray sagt, "mehr in den F # Sprachen zuhause". Nicht schlecht für 21 Zeilen Code (und ein paar Layout/Benennungsempfehlungen). Zwei schnelle Notizen: 1. Die vorkompilierte FSUnit DLL funktionierte nicht für mich. Das Erstellen aus der Quelle (FsUnit.NUnit-0.9.0.fs) behob das Problem. 2. TestDriven.Net erkennt keine TextFixture-Namen, die '\' so aussehen \ ". Testnamen, die das Doppeltick-Formular verwenden, werden erkannt. –

10

Wie dglasman empfiehlt, können Sie NUnit verwenden. xUnit.net bietet auch Unterstützung dafür und funktioniert gut mit TestDriven.net. Der Code ähnelt NUnit-Tests, jedoch ohne dass der Test in einen Containertyp eingebettet werden muss.

#light 

// Supply a module name here not a combination of module and namespace, otherwise 
// F# cannot resolve individual tests nfrom the UI. 
module NBody.DomainModel.FSharp.Tests 

open System 
open Xunit 

open Internal 

[<Fact>] 
let CreateOctantBoundaryReordersMinMax() = 
    let Max = VectorFloat(1.0, 1.0, 1.0) 
    let Min = VectorFloat(-1.0, -1.0, -1.0) 

    let result = OctantBoundary.create Min Max 

    Assert.Equal(Min, result.Min)  
    Assert.Equal(Max, result.Max) 
+0

Ab 1.9.1 scheinen Xunits neue Überladungen mit meiner F # verheerend zu sein. –

+0

@RickMinerich Ich habe das Gleiche mit meinem Code passiert. Ich habe gerade explizite Typ Anmerkungen hinzugefügt, so dass die richtige Überladung gewählt würde. Dieses * fügt Ihrem Code leider mehr Rauschen hinzu. –