# How do you approach Html testing?

**URL:** <https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459>\
**Category:** Learn\
**Created:** [October 9, 2019, 5:41pm UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459 "2019-10-09T17:41:40Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![michaeljones](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/michaeljones/32/152_2.png) [@michaeljones](https://discourse.elm-lang.org/u/michaeljones)\
**Post date:** [October 9, 2019, 5:41pm UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/1 "2019-10-09T17:41:40Z")

</div>

My company has quite a large Elm app (100k lines) and we have some unit tests for decoders and for nice testable algorithmic functions. We have one or two end-to-end tests. We don’t have any Test.Html tests.

I feel like I should write more end-to-end tests but then I feel like they take a long time to write and I should be maximising on what elm-test can offer to write faster, neater tests and therefore should be trying to use Test.Html. (Aside, I realise I should have more tests in general.)

But when I look at the module help, I’m not really sure what to test for. And I guess I’m torn. On the one hand some of my unit tests are for super basic for things that appear to be obvious from the code and so almost seem crazy to test for and, on the other hand, when I look at what sort of Html tests I might write they seem kind of super basic and obvious from the code and crazy to test for so I find myself not writing them.

Can anyone help me by sharing the kind of Html tests they write and the sort of things that they prove to be useful for?

---

<div class="post-metadata">

**Author:** ![berend](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/berend/32/2250_2.png) [@berend](https://discourse.elm-lang.org/u/berend)\
**Post date:** [October 9, 2019, 9:24pm UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/2 "2019-10-09T21:24:28Z")

</div>

I couldn’t image making changes to our app without our extensive Behat (BDD, Gherkin) based tests.

---

<div class="post-metadata">

**Author:** ![Chadtech](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/chadtech/32/609_2.png) [@Chadtech](https://discourse.elm-lang.org/u/Chadtech)\
**Post date:** [October 10, 2019, 5:46am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/3 "2019-10-10T05:46:34Z")

</div>

I have done a few different things.

**Bad idea : Taking snapshots of the dom**  
I was working on a team where the tests would render the html, and then diff it against some known good html we had saved to a file. If there were any differences the tests would fail. The problem was that dom changes arent problems. Almost 100% of the time the dom changes, its because the developer is deliberately changing the dom as part of whatever they are working on.

**Good idea : Verifying particular dom transitions**  
Suppose you want the UI to transition to a loading state after you click “save”, and you dont want this to break unexpectedly. You can test for this by having a computer automatically click that save button, and then automatically scan the the dom for some kind of loading spinner html element. If its missing, then the test fails.

**(Experimental?) Good idea : Custom types**  
View functions go from state to html, like this.

```auto
view : Model -> Html Msg

```

And you cant really test `Html Msg`; both because `Html Msg` is opaque, and because `Html Msg` changing isnt a failure case. However, if you generalize your views into some finite set, like this:

```elm
type View
    = Ready
    | Loading
    | Done

```

and then have functions like these:

```auto
view : Model -> View

toHtml : View -> Html Msg

```

Then you can test that certain `Msg` and `Model` lead to certain `View`, without worrying about what actual dom nodes are supposed to appear. This should let you develop and change the `Ready` view, without causing the test to fail, while still verifying big important questions, like that the `Ready` view is what is shown when it should be shown.

---

<div class="post-metadata">

**Author:** ![michaeljones](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/michaeljones/32/152_2.png) [@michaeljones](https://discourse.elm-lang.org/u/michaeljones)\
**Post date:** [October 10, 2019, 8:35am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/4 "2019-10-10T08:35:08Z")

</div>

> [@berend](#):
>
> I couldn’t image making changes to our app without our extensive Behat (BDD, Gherkin) based tests.

My understanding is that that would be a end-to-end testing set up? Rather than using the `Test.Html` Elm module? Or is Gherkin more a way to phrase a certain kind of test and you still implement them with `Test.Html`?

---

<div class="post-metadata">

**Author:** ![michaeljones](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/michaeljones/32/152_2.png) [@michaeljones](https://discourse.elm-lang.org/u/michaeljones)\
**Post date:** [October 10, 2019, 8:41am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/5 "2019-10-10T08:41:45Z")

</div>

I’m really interested to hear a vote against snapshot testing. It seems like it is getting quite popular but I agree with your argument that it perhaps isn’t the right level of granularity to test it. There is a bit of discussion on this `elm-test` ticket too: [https://github.com/elm-community/elm-test/issues/209](https://github.com/elm-community/elm-test/issues/209) (including a previous hopeful inquiry from me!)

Is the second example something that can be achieved with `Test.Html`? Perhaps it isn’t and perhaps I wasn’t as clear as I should have been in the question. I’m partially interested in what sort of tests people write with `Test.Html`. Perhaps that is manageable but it feels more like a full view & update & view test? Is that possible with the Elm Test modules rather than a browser based testing framework? If people aren’t using `Test.Html` though, I’m also curious what people do use and what sort of tests they write.

You’re third example seems to explicitly be trying to avoid using `Test.Html` which is interesting. Perhaps `Test.Html` does provide enough introspection tools to achieve what you’re interested in? Good to see as an example though!

Thanks for the reply.

---

<div class="post-metadata">

**Author:** ![berend](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/berend/32/2250_2.png) [@berend](https://discourse.elm-lang.org/u/berend)\
**Post date:** [October 10, 2019, 6:57pm UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/6 "2019-10-10T18:57:19Z")

</div>

> [@michaeljones](#):
>
> My understanding is that that would be a end-to-end testing set up?

Yes, that’s the whole idea. You just test the app like a user does. No Test.html. You write your tests in a special syntax (Gherkin), which looks like this:

```gherkin
Scenario: Resetting password
  Given I login for the first time
  And I logout

  When I fill in "Email" with "my email address"
  And I follow "Forgot password?"
  Then I should see "Password reset instructions will be sent"
  And the "Email" field should contain "my email address"

  When I press "Email new password"
  Then I should see "Please click on the link in the email to reset your password."
  And a new email with subject containing "Replacement login information" has arrived for "my email address"

  When I press "OK"
  Then I should see "Forgot password?"
  And the "Password" field should contain ""

  When I visit "the first link in the last email"
  And I fill in "New password" with "abc123"
  And I fill in "Re-enter password" with "abc123"
  And I press "Update password"
  Then I should see "Hi Mrs, let's measure your impact"

```

Much more in the highly recommended [Cucumber book](https://pragprog.com/book/hwcuc/the-cucumber-book).

---

<div class="post-metadata">

**Author:** ![Chadtech](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/chadtech/32/609_2.png) [@Chadtech](https://discourse.elm-lang.org/u/Chadtech)\
**Post date:** [October 10, 2019, 7:28pm UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/7 "2019-10-10T19:28:29Z")

</div>

> [@michaeljones](#):
>
> Is the second example something that can be achieved with `Test.Html` ?

Looks like it. But, I didnt know about `Test.Html`. Thank you for pointing that out! Thats a huge help.

---

<div class="post-metadata">

**Author:** ![Nick\_S](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/nick_s/32/2580_2.png) [@Nick\_S](https://discourse.elm-lang.org/u/Nick_S)\
**Post date:** [October 11, 2019, 5:52am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/8 "2019-10-11T05:52:23Z")

</div>

I’ve read a article recently on Gherkin but I’ve not made an effort to learn it and use it in a project yet. You have used this development style with an Elm project with good results? And is this on top of any unit testing?

---

<div class="post-metadata">

**Author:** ![berend](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/berend/32/2250_2.png) [@berend](https://discourse.elm-lang.org/u/berend)\
**Post date:** [October 11, 2019, 6:30am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/9 "2019-10-11T06:30:53Z")

</div>

> [@Nick\_S](#):
>
> ou have used this development style with an Elm project with good results?

Have used Behat for years. I can’t say I’m really a strict BDD guy, although I’m strict that for every bug report I create a test that reproduces it, and only then fix the bug.

Have used Elm for about 1 year, and have used Behat for every Elm project I’ve done. I do continuous delivery, so many live app updates a day, and it’s extremely rare to introduce a bug.

---

<div class="post-metadata">

**Author:** ![klaftertief](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/klaftertief/32/5338_2.png) [@klaftertief](https://discourse.elm-lang.org/u/klaftertief)\
**Post date:** [October 11, 2019, 7:45am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/10 "2019-10-11T07:45:15Z")

</div>

There also is [https://package.elm-lang.org/packages/avh4/elm-program-test/3.1.0/](https://package.elm-lang.org/packages/avh4/elm-program-test/3.1.0/) for “testing your Elm programs as complete units”. Though you have to write the effecful parts of your program in a specific manner to fully use it. [https://elm-program-test.netlify.com/](https://elm-program-test.netlify.com/) describes it nicely. (Though I have to say I have not used it yet.)

---

<div class="post-metadata">

**Author:** ![michaeljones](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/michaeljones/32/152_2.png) [@michaeljones](https://discourse.elm-lang.org/u/michaeljones)\
**Post date:** [October 11, 2019, 11:00am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/11 "2019-10-11T11:00:01Z")

</div>

That’s really interesting! Thanks for sharing. I can see the value in that more clearly than pure Test.Html tests.

[edit - regarding: [https://package.elm-lang.org/packages/avh4/elm-program-test/3.1.0/](https://package.elm-lang.org/packages/avh4/elm-program-test/3.1.0/)]

---

<div class="post-metadata">

**Author:** ![paulh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/paulh/32/5022_2.png) [@paulh](https://discourse.elm-lang.org/u/paulh)\
**Post date:** [October 15, 2019, 12:53am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/12 "2019-10-15T00:53:28Z")

</div>

I was looking for an end to end testing solution, and came across [Cypress](https://www.cypress.io) which I’ve been using successfully for a couple of months now.

I found it to be simple to set up, and comes with some neat features like time travel, automatic reloads when you change your tests, and automatic waiting for elements to load so you don’t need to add waits to your tests.

It will also take snapshots and videos of the test runs.

You can use the test runner locally, and the dashboard service to integrate with Github and CI/CD provider.

(I also just started using [Percy](https://percy.io) for visual testing, which integrates nicely with Cypress, Github, CI/CD)

---

<div class="post-metadata">

**Author:** ![francescortiz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/francescortiz/32/1721_2.png) [@francescortiz](https://discourse.elm-lang.org/u/francescortiz)\
**Post date:** [October 16, 2019, 11:17am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/13 "2019-10-16T11:17:14Z")

</div>

The caveats of cypress are:

- It only supports Chrome.
- It only supports JavaScript.
- It triggers virtual events, not actual browser events. You have no certainty that what was clicked was actually clickable.

If you worry about these points give a look to selenium.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [October 26, 2019, 11:23am UTC](https://discourse.elm-lang.org/t/how-do-you-approach-html-testing/4459/14 "2019-10-26T11:23:26Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
