Write unit and fuzz tests for Elm code.
Here are three example tests:
suite : Test
suite =
describe "The String module"
[ describe "String.reverse" -- Nest as many descriptions as you like.
[ test "has no effect on a palindrome" <|
\_ ->
let
palindrome =
"hannah"
in
Expect.equal palindrome (String.reverse palindrome)
-- Expect.equal is designed to be used in pipeline style, like this.
, test "reverses a known string" <|
\_ ->
"ABCDEFG"
|> String.reverse
|> Expect.equal "GFEDCBA"
-- fuzz runs the test 100 times with randomly-generated inputs!
, fuzz string "restores the original string if you run it again" <|
\randomlyGeneratedString ->
randomlyGeneratedString
|> String.reverse
|> String.reverse
|> Expect.equal randomlyGeneratedString
]
]
This code uses a few common functions:
describe
to add a description string to a list of teststest
to write a unit testExpect
to determine if a test should pass or failfuzz
to run a function that produces a test several times with randomly-generated
inputsCheck out a large real-world test suite for more.
Here’s how to set up and run your tests using the CLI test runner:
npm install -g elm-test
if you haven’t already.cd
into the project’s root directory that has your elm.json
.elm-test init
. It will create a tests
directory inside this one, with
some files in it.elm-test
.tests/Example.elm
to introduce new tests.Hint: If you have dependencies add them via
elm-test install authorName/dependencyName
. Bonus hint: Run elm-test --watch
to rerun your tests whenever a file is saved.
Here are some examples of running tests on CI servers:
During development, you’ll often want to focus on specific tests, silence
failing tests, or jot down many ideas for tests that you can’t implement all at
once. We’ve got you covered with skip
, only
, and todo
:
wipSuite : Test
wipSuite =
describe "skip, only, and todo"
[ only <|
describe "Marking this test as `only` means no other tests will be run!"
[ test "This test will be run" <|
\_ -> 1 + 1 |> Expect.equal 2
, skip <| test "This test will be skipped, even though it's in an `only`!" <|
\_ -> 2 + 3 |> Expect.equal 4
]
, test "This test will be skipped because it has no `only`" <|
\_ -> "left" |> Expect.equal "right"
, todo "Make sure all splines are reticulated"
]
If you run this example, or any suite that uses one of these three functions, it will result in an incomplete test run. No tests failed, but you also didn’t run your entire suite, so we can’t call it a success either. Incomplete test runs are reported to CI systems as indistinguishable from failed test runs, to safeguard against accidentally committing a gutted test suite!
There are a few extra ideas that apply to testing webapps and reusable view packages:
Main
module. Most of your code belongs in other
modules, so import those instead.Test.Html.Query
, Test.Html.Selector
, and
Test.Html.Event
.