Testing in Elm

Thomas Brisbout

Freelance JS developer

 @tbrisbout

Elm Paris Meetup / 2016-06-21

elm-test

Init

# Adds the Elm-Test dependency and 
# creates TestRunner.elm and Tests.elm

elm-test init

# Runs the tests

elm-test tests/TestRunner.elm 

Does not work in 0.17 currently

npm script workaround

// package.json

"scripts": {
  "pretest": "elm-make tests/TestRunner.elm \
              --output tests.js",
  
  "test": "node tests.js || true"
}

Modified TestRunner.elm

Module Main exposing (..)

import ElmTest exposing (..)
import Tests


tests : Test
tests =
    Tests.all


main : Program Never
main =
    runSuite tests

Test Suite

Module Tests exposing (..)

import String
import ElmTest exposing (..)

tests : Test
tests =
    suite "A Test Suite"
        [ test "Addition" 
               (assertEqual (3 + 7) 10)
        , test "String.left" 
               (assertEqual "a" (String.left 1 "abcdefg"))
        , test "This test should fail" 
                (assert False)
        ]

Output

$ npm test
...

Success! Compiled 2 modules.                                        
Successfully generated tests.js

...

The message provided by the code author is:

  1 suites run, containing 3 tests
  0 suites and 2 tests passed
  1 suites and 1 tests failed

Test Suite: A Test Suite: FAILED
  Addition: passed.
  String.left: passed.
  This test should fail: FAILED. not True

elm-bdd-style

BDD describe / it / expect

import ElmTestBDDStyle exposing (..)


tests : Test
tests =
    describe "A Test Suite"
        [ it "adds two numbers"
            <| expect (3 + 7) toBe 10
        , it "fails for non-sense stuff"
            <| expect True toBe False
        ]

elm-check

elm-check

Property-based Testing

Test Claims

myClaims : Claim
myClaims =
  suite "List Reverse"
    [ claim
        "Reversing a list twice yields the original list"
      `that`
        (\list -> reverse (reverse list))
      `is`
        identity
      `for`
        list int

    , claim
      "Reversing a list does not modify its length"
    `that`
      (\list -> length (reverse list))
    `is`
      (\list -> length list)
    `for`
      list int
    ]

Evidence and suite

import ElmTest exposing (runSuite)
import Check exposing (..)
import Check.Test exposing (evidenceToTest)
import Check.Producer exposing (int, list)

{-- 
Claims
--}

evidence : Evidence
evidence =
    quickCheck myClaims

main =
    runSuite <| evidenceToTest evidence

project-fuzzball

Future elm-test runner & API

init and run ok in 0.17

$ elm-test
Some new packages are needed. Here is the upgrade plan.

  Install:
    elm-community/elm-lazy-list 1.0.1
    elm-community/shrink 1.1.0
    elm-lang/core 4.0.1
    elm-lang/html 1.0.0
    elm-lang/lazy 1.0.0
    elm-lang/virtual-dom 1.0.2
    mgold/elm-random-pcg 2.1.1
    project-fuzzball/node 1.0.0
    project-fuzzball/test 1.2.0
    project-fuzzball/test-runner 1.0.0

Do you approve of this plan? (y/n) 
$ elm-test init
Created /home/thomas/work/dev/elm/elm-testing/new/src
Created /home/thomas/work/dev/elm/elm-testing/new/tests
Created /home/thomas/work/dev/elm/elm-testing/new/tests/elm-package.json
Created /home/thomas/work/dev/elm/elm-testing/new/tests/TestRunner.elm
Created /home/thomas/work/dev/elm/elm-testing/new/tests/Tests.elm
Created /home/thomas/work/dev/elm/elm-testing/new/tests/.gitignore

New TestRunner.elm

port module Main exposing (..)

import Tests
import Test.Runner.Node exposing (run)
import Json.Encode exposing (Value)


main : Program Never
main =
    run emit Tests.all


port emit : ( String, Value ) -> Cmd msg

New API

all : Test
all =
    describe "A Test Suite"
        [ test "Addition"
            <| \_ ->
                Assert.equal (3 + 7) 10
        , test "String.left"
            <| \_ ->
                Assert.equal "a" (String.left 1 "abcdefg")
        , test "This test should fail"
            <| \_ ->
                Assert.fail "failed as expected!"
        ]

Better console output

Testing order

Type

Property based testing

Unit Testing

`andThen`

`andThen`

References

Questions ?

Made with Slides.com