F # desarrollo y pruebas unitarias?


Acabo de empezar con F#, que es mi primer lenguaje funcional. He estado trabajando casi exclusivamente con C#, y disfruto mucho de cómo F # me lleva a repensar cómo escribo código. Un aspecto que encuentro un poco desorientador es el cambio en el proceso de escribir código. He estado usando TDD durante años en C# ahora, y realmente aprecio tener pruebas unitarias para saber dónde estoy.

Hasta ahora, mi proceso con F# ha sido escribir algunas funciones, jugar con ellas con la consola interactiva hasta que estoy "razonablemente" seguro de que funcionan, y ajustar y combinar. Esto funciona bien en problemas a pequeña escala como el Proyecto Euler, pero no puedo imaginar construir algo grande de esa manera.

¿Cómo abordan las personas las pruebas unitarias y la construcción de un conjunto de pruebas para un programa F#? Hay un equivalente a TDD? Cualquier consejo o pensamiento es apreciado.

Author: knocte, 2010-01-01

6 answers

Los desarrolladores basados en pruebas deben sentirse como en casa en lenguajes funcionales como F#: las funciones pequeñas que dan resultados determinísticamente repetibles se prestan perfectamente a las pruebas unitarias. También hay capacidades en el lenguaje F# que facilitan las pruebas de escritura. Tomemos, por ejemplo, Expresiones de objeto. Puede escribir fácilmente falsificaciones para funciones que toman como entrada un tipo de interfaz.

En todo caso, F # es un lenguaje orientado a objetos de primera clase y puede utilizar el las mismas herramientas y trucos que usas cuando haces TDD en C#. También hay algunas herramientas de prueba escritas o específicamente para F#:

Matthew Podwysocki escribió una gran serie sobre pruebas unitarias en lenguajes funcionales. El tío Bob también escribió un artículo que invita a la reflexión aquí .

 72
Author: Ray Vernagus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-19 10:40:56

Uso NUnit, y no me parece tan difícil leer o oneroso escribir:

open NUnit.Framework

[<TestFixture>]
type myFixture() = class

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

end

Dado que mi código es una mezcla de F# y otros lenguajes.Net, me gusta el hecho de que escribo las pruebas unitarias básicamente de la misma manera y con una sintaxis similar tanto en F# como en C#.

 21
Author: David Glaubman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-06 18:53:58

Echa un vistazo a FsCheck , una herramienta de prueba automática para F#, es básicamente un puerto del QuickCheck de Haskell. Le permite proporcionar una especificación de el programa, en forma de propiedades que las funciones o métodos deben satisfacer, y pruebas FsCheck que las propiedades tienen en un gran número de casos generados aleatoriamente.

FsCheck CodePlex Page

FsCheck Author Page

 14
Author: primodemus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-03 12:16:43

Como dglaubman sugiere, puedes usar NUnit. xUnit.net {[3] } también proporciona soporte para esto y funciona bien con TestDriven.net. El código es similar a las pruebas NUnit pero sin el requisito de envolver la prueba en un tipo contenedor.

#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) 
 10
Author: Ade Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-07 03:29:27

Creo que esta es una pregunta muy interesante sobre la que me he preguntado mucho. Mis pensamientos hasta ahora son solo pensamientos, así que tómalos por lo que son.

Creo que la red de seguridad de un conjunto de pruebas automatizadas es un activo demasiado valioso para dejar ir, por muy atractiva que pueda ser esa consola interactiva, así que planeo continuar escribiendo pruebas unitarias como siempre lo he hecho.

Uno de los principales puntos fuertes de.NET son las capacidades de varios idiomas. Sé que voy a escribir F# código de producción pronto, pero mi plan es escribir pruebas unitarias en C# para facilitar mi camino en lo que es para mí un nuevo lenguaje. De esta manera, también puedo probar que lo que escribo en F# será compatible con C# (y otros lenguajes.NET).

Con este enfoque, entiendo que hay ciertas características de F# que solo puedo usar internamente en mi código F#, pero no exponer como parte de mi API pública, pero aceptaré eso, al igual que acepto hoy que hay ciertas cosas que C# me permite expresar (como uint) que no son compatibles con CLS, por lo que me abstengo de usarlos.

 10
Author: Mark Seemann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-07 12:50:18

Podrías echar un vistazo a FSUnit - aunque todavía no lo he usado, podría valer la pena intentarlo. Ciertamente mejor que usar, por ejemplo, NUnit (nativo) en F#.

 6
Author: ShdNx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-24 22:38:56