Elm ya es famoso por su compilador que evita errores en tiempo de ejecución, pero eso no significa que las pruebas no sean necesarias.
De hecho, los tests en Elm complementan su sistema de tipos, ayudándote a verificar la lógica de negocio, las transformaciones de datos y el comportamiento de tus funciones puras.
A diferencia de otros lenguajes donde los tests buscan prevenir errores de nulls, tipos o efectos secundarios, en Elm los tests sirven principalmente para:
- Asegurar que una función devuelva el resultado esperado.
- Comprobar que una actualización de modelo (en TEA) cambie el estado correctamente.
- Validar transformaciones de datos o funciones puras de negocio.
Gracias a la pureza funcional, las pruebas en Elm son simples y predecibles.
El framework oficial de testing es elm-test.
Instalalo con:
npm install -g elm-test
elm-test init
Esto crea una carpeta:
tests/
└── Example.elm
donde podrás escribir tus pruebas.
Supongamos que tenés una función en src/MathUtils.elm:
module MathUtils exposing (add)
add : Int -> Int -> Int
add a b =
a + b
Podés crear un test en tests/MathUtilsTest.elm:
module MathUtilsTest exposing (tests)
import Expect
import Test exposing (..)
import MathUtils exposing (add)
tests : Test
tests =
describe "Pruebas de MathUtils"
[ test "Suma básica" <|
\_ -> Expect.equal 4 (add 2 2)
, test "Suma con negativos" <|
\_ -> Expect.equal 0 (add 2 -2)
]
Ejecutalo con:
elm-test
y deberías ver algo como:
TEST RUN PASSED
Duration: 15 ms
Podés probar también las funciones update de tu arquitectura Elm.
Supongamos una aplicación simple que incrementa un contador:
type alias Model =
{ counter : Int }
type Msg
= Increment
update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
{ model | counter = model.counter + 1 }
El test sería:
module CounterTest exposing (tests)
import Expect
import Test exposing (..)
import Main exposing (update, Model(..), Msg(..))
tests : Test
tests =
describe "Update del contador"
[ test "Incrementa el contador" <|
\_ ->
let
model = { counter = 0 }
updated = update Increment model
in
Expect.equal 1 updated.counter
]
Expect.notEqual – asegura que dos valores sean diferentes.
Expect.true / Expect.false – comprueba booleanos.
Expect.all – combina varios asserts sobre el mismo valor.
Fuzz tests – pruebas con datos aleatorios (muy útiles para funciones matemáticas o validaciones).
Ejemplo de fuzzing:
import Fuzz exposing (int)
fuzzTest : Test
fuzzTest =
fuzz int "Suma con cero no cambia el número" <|
\n -> Expect.equal n (add n 0)
El fuzzer genera cientos de casos aleatorios para asegurar que la propiedad siempre se cumple.
El sistema de tipos de Elm ya evita gran parte de los errores comunes, pero las pruebas unitarias llevan esa confianza un paso más allá. Te permiten documentar y verificar el comportamiento de tus funciones de forma declarativa, legible y segura.
