DEV Community

Cover image for Elm Calculator Part 10 - Testing
Ryan Frazier
Ryan Frazier

Posted on • Originally published at on

Elm Calculator Part 10 - Testing

This post is part of a series. To see all published posts in the series see the tag "elm calculator book".If you wish to support my work you can purchase the book on gumroad.

This project uses Elm version 0.19

  • Part 1 - Introduction
  • Part 2 - Project Setup
  • Part 3 - Add CSS
  • Part 4 - Basic Operations
  • Part 5 - Adding Decimal Support
  • Part 6 - Supporting Negative Numbers
  • Part 7 - Add Dirty State
  • Part 8 - Support Keypad Input
  • Part 9 - Combination Key Input
  • Part 10 - Testing (this post)
  • Part 11 - Netlify Deployment

Note: ellie-app does not support splitting out your code into modules and files. So there is no ellie link for this chapter.

We will be using a newer Elm package called elm-program-test. It allows us to test our application as a whole. It will stand up the application and allow us to test it as if a user were clicking through the application.

Some Refactoring

In order to test our program we need to expose some of our functions in Main.elm.

module Main exposing (Model, Msg, init, main, update, view)
Enter fullscreen mode Exit fullscreen mode

We also need to make our elm program use Browser.document instead of Browser.element since we will be using ProgramTest.createDocument.

Elm has different ways to create a program. Browser.element is good for creating a small elm application that you embed into the page on a specific DOM node. What if you want Elm to take over the whole page? That is what Browser.document is for. See the elm-guide for more information about Browser.element and Browser.document.

Note: Since creating this book, I have since learned that you can use ProgramTest.createElement instead and we wouldn't need to do this refactor.

Refactoring is lovely in Elm. Our first step is to start at the highest level of our refactor and let the compiler tell us what to change. So start by changing the main function to return a Browser.document instead of a Browser.element.

The only thing we need to change for this refactor is the view function to return a Browser.Document instead of Html.

The difference with Browser.Document is that the view function now needs a record with a title and a body field. We can place our previous view html stuffs inside the body field.

view : Model -> Browser.Document Msg
view model =
    { title = "Elm Calculator"
    , body =
        [div []
            [h1 [ class "h1"] [text "RPN Calculator"]
    , ...
Enter fullscreen mode Exit fullscreen mode

Write the test

First we need to install everything we need. We need the elm-test command line program because we need something to launch and execute our tests. This is our test runner if you have used something like pytest.

npm install --save-dev elm-test
Enter fullscreen mode Exit fullscreen mode

We also need to install the corresponding elm packages as well.

elm install elm-explorations/test
elm install avh4/elm-program-test
Enter fullscreen mode Exit fullscreen mode

To get a simple example test run elm-test init in your project folder.

npx elm-test init
Enter fullscreen mode Exit fullscreen mode

Now run the test you just created.

npx elm-test
Enter fullscreen mode Exit fullscreen mode

You should get a test report.

Create a new file in the tests directory called CalculatorTest.elm.

The test is short (less than 40 lines of code). I'll walk through the most interesting part.

all : Test
all =
    describe "basic arithmetic"
    [ test "20 × 3 = 60" <|
        \() ->
                |> clickCalcBtn "2"
                |> clickCalcBtn "0"
                |> clickCalcBtn "←"
                |> clickCalcBtn "3"
                |> clickCalcBtn "×"
                |> expectViewHas
                    [ text "60"
Enter fullscreen mode Exit fullscreen mode

This simulates a user clicking on the number and operator buttons. It then checks that the number 60 is somewhere on the page. Try playing with this and adding another test.

The next and last chapter will cover deploying our Elm application to netlify. If you got this far, congratulations! We're almost finished. I get a lot of satisfaction with web projects because they are so easy to share with the world. I'll show you how in the next chapter.

Top comments (2)

chemacortes profile image
Chema Cortés

I'm still a newbie, but development packages should be installed with elm-test install, not elm install. Also, the elm-test init command do install the elm-test package. Only need to install elm-program-test.

pianomanfrazier profile image
Ryan Frazier

Your way is probably better. Thanks for the tip.