108 votes

Développement F# et tests unitaires ?

Je viens de commencer avec F#, qui est mon premier langage fonctionnel. J'ai travaillé presque exclusivement avec C#, et j'apprécie beaucoup la façon dont F# m'amène à repenser ma façon d'écrire du code. Un aspect que je trouve un peu désorientant est le changement dans le processus d'écriture du code. J'utilise le TDD depuis des années en C# maintenant, et j'apprécie vraiment d'avoir des tests unitaires pour savoir où j'en suis.

Jusqu'à présent, mon processus avec F# a été d'écrire quelques fonctions, de jouer avec elles avec la console interactive jusqu'à ce que je sois "raisonnablement" sûr qu'elles fonctionnent, puis de les modifier et de les combiner. Cela fonctionne bien sur des problèmes à petite échelle comme le projet Euler, mais je ne peux pas imaginer construire quelque chose de plus grand de cette façon.

Comment les gens abordent-ils les tests unitaires et la création d'une suite de tests pour un programme F# ? Existe-t-il un équivalent du TDD ? Toute indication ou réflexion est la bienvenue.

1 votes

expert-fsharp.com/CodeSamples/Forms/ montre un exemple simple d'utilisation de NUnit avec F#.

0 votes

0 votes

Liés : stackoverflow.com/questions/5667372/ (Unquote est bien plus qu'une note de bas de page/un commentaire car il se trouve dans le jeu de réponses de cette page).

77voto

Ray Vernagus Points 4276

Les développeurs axés sur les tests devraient se sentir chez eux dans les langages fonctionnels comme F# : les petites fonctions qui donnent des résultats répétables de manière déterministe se prêtent parfaitement aux tests unitaires. Le langage F# possède également des capacités qui facilitent l'écriture de tests. Prenons l'exemple suivant, Expressions d'objets . Vous pouvez très facilement écrire des fakes pour les fonctions qui prennent comme entrée un type d'interface.

En fait, F# est un langage orienté objet de première classe et vous pouvez utiliser les mêmes outils et astuces que pour le TDD en C#. Il existe également des outils de test écrits en F# ou spécifiquement pour ce langage :

Matthew Podwysocki a écrit un grand série sur les tests unitaires dans les langages fonctionnels. Oncle Bob a également écrit un article qui suscite la réflexion. ici .

9 votes

J'ai également développé (et je développe activement) une bibliothèque de tests unitaires spécifique à F#, appelée Unquote : code.google.com/p/unquote . Il vous permet d'écrire des assertions de test en tant qu'expressions booléennes F# simples, vérifiées statiquement, en utilisant les cotations F# et produit automatiquement de beaux messages d'échec de test. Il fonctionne sans configuration avec un support spécial pour xUnit.net et NUnit et supporte généralement tout cadre de test unitaire basé sur les exceptions. Il fonctionne même dans les sessions FSI, ce qui permet une migration transparente des tests interactifs vers des suites de tests formelles.

0 votes

Il y a Pex aussi, même si c'est un peu plus difficile à comprendre.

1 votes

Le lien d'Oncle Bob semble mort

22voto

David Glaubman Points 186

J'utilise NUnit, et il ne me semble pas difficile à lire ou onéreux à écrire :

open NUnit.Framework

[<TestFixture>]
type myFixture() = class

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

end

Comme mon code est un mélange de F# et d'autres langages .Net, j'apprécie le fait que je puisse écrire les tests unitaires de la même manière et avec une syntaxe similaire en F# et en C#.

4 votes

Après avoir lu d'autres réponses ici, j'ai essayé FSUnit, et je pense que c'est génial. Il fonctionne bien avec TestDriven.Net (tout comme NUnit), encourage un style fluide d'écriture de tests auto-documentés et, comme le dit Ray, est "plus à l'aise dans les langages F#". Pas mal pour 21 lignes de code (et quelques recommandations de mise en page et de nommage). Deux notes rapides : 1. La DLL précompilée de FSUnit n'a pas fonctionné pour moi. La construction à partir des sources (FsUnit.NUnit-0.9.0.fs) a réglé le problème. 2. TestDriven.Net ne reconnait pas les noms de TextFixture qui ressemblent à `like this` . Les noms de tests utilisant la forme double-tick sont reconnus.

14voto

primodemus Points 401

Jetez un coup d'œil à FsCheck un outil de test automatique pour F#, est essentiellement un portage de QuickCheck de Haskell. portage de QuickCheck de Haskell. Il vous permet de fournir une spécification du du programme, sous la forme de propriétés que les fonctions ou les méthodes doivent satisfaire, et FsCheck teste que les propriétés sont valables dans un grand nombre de cas générés aléatoirement.

Page FsCheck CodePlex

Page d'auteur de FsCheck

0 votes

Oui, je pense que FsCheck offre beaucoup plus que les cadres traditionnels de tests unitaires tels que NUnit, etc.

11voto

Mark Seemann Points 102767

Je pense que c'est une question très intéressante sur laquelle je me suis moi-même beaucoup interrogé. Mes réflexions jusqu'à présent ne sont que des réflexions, alors prenez-les pour ce qu'elles sont.

Je pense que le filet de sécurité d'une suite de tests automatisés est un atout trop précieux pour être abandonné, aussi séduisante que soit la console interactive, et je prévois donc de continuer à écrire des tests unitaires comme je l'ai toujours fait.

L'une des principales forces de .NET réside dans ses capacités inter-langues. Je sais que je vais bientôt écrire du code de production F#, mais j'ai l'intention d'écrire des tests unitaires en C# pour me familiariser avec ce qui est pour moi un nouveau langage. De cette façon, je peux également vérifier que ce que j'écris en F# sera compatible avec C# (et les autres langages .NET).

Avec cette approche, je comprends qu'il y a certaines fonctionnalités de F# que je ne peux utiliser qu'en interne dans mon code F#, mais que je ne peux pas exposer dans le cadre de mon API publique, mais je l'accepterai, tout comme j'accepte aujourd'hui qu'il y a certaines choses que C# me permet d'exprimer (par exemple uint ) qui ne sont pas conformes aux normes CLS, et je m'abstiens donc de les utiliser.

2 votes

Comment s'est déroulé votre plan ? C'était facile de tester le code f# avec le code c# ? J'ai commencé à apprendre f# et mon plan est d'écrire une partie de mon projet en f# et j'ai la même idée : écrire des tests unitaires en c# pour f# aussi.

0 votes

@Mark : des mises à jour ? J'ai également du mal à me lancer dans l'utilisation de TDD avec F#.

1 votes

@ScottNimrod Pas mal de mises à jour : quatre de mes cours Pluralsight sont sur les tests ou TDD avec F#. Vous trouverez également de nombreux enregistrements gratuits de conférences sur le site mon profil Lanyrd . Enfin, il y a mon blog .

11voto

Ade Miller Points 7750

Comme le suggère dglaubman, vous pouvez utiliser NUnit. xUnit.net fournit également un support pour cela et fonctionne bien avec TestDriven.net . Le code ressemble aux tests NUnit mais sans l'obligation d'envelopper le test dans un type contenant.

#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 votes

Depuis la version 1.9.1, les nouvelles surcharges de Xunit semblent causer des problèmes avec mon F#.

0 votes

@RickMinerich J'ai connu la même chose dans mon code. J'ai juste fini par ajouter des annotations de type explicites afin que la surcharge correcte soit choisie. Cependant, cette fait ajouter plus de bruit à votre code malheureusement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X