How do you test your frontend?

Hi all,

So I have a fairly sizeable Clojurescript application and I’ve been struggling with getting a good test suite going for it for a while now.

I do have some cljs tests against certain namespaces in my frontend code which deal with data manipulation etc. But I am not so sure what to do about testing the frontend UI interactions. Its hard to avoid regressions completely but I would like to catch the rather critical ones which interrupt user workflow.

I was wondering what everyone is doing with regards to this in their user facing applications based on Clojurescript, or even Javascript.

Thanks,
verma

Aside:
I had a Clojure+Selenium project where I developed quite a bit of DSL to test my specific app, it was actually quite a nice experience since interaction through REPL was very convenient when you’re testing certain one-step interactions. Easy to keep calling a function to see if a button click is working the right way etc. It was a lot of fun, but even that I am unable to keep up with, because the exciting problem is solved and now its just mindless test building :(.

Perhaps I could further enhance it to a degree where some one else could write the tests, like a custom tool internal tool available to (test) engineers.

1 Like

Selenium is indeed very pleasant to drive with Clojure!

Another major immediate asset is “pure functions”, or at least functions that are pure with respect to their effect on test-side data structures! Because any action that touches a running browser, even just to look at it or find a detail on the page, may fail. It may catch the browser “in between” DOM states, or whatever. Clojure is a great tool to make retry-loop-safe procedures.

You refer to (test) engineers as if… without much hope of… er…

Thanks for your response.

I’m sorry, I am not following :(.

I was referring to two classes of engineers: one, who are particularly geared towards using QA/test engineering, and second, engineers who are developing a feature and want to write tests to go with. I guess some FE frameworks fit the bill there but there’s always that slight hindrance to get it rolling nicely.

From what experience I have with frontend tests… the ones that test the interactions themselves using some frontend testing framework tend to be so coupled to either the CSS/HTML code or the visual appearance as to make any kind of refactoring or redesign extremely tedious, so I don’t bother with those at all. To me, UI is something I iterate on all the time, it’s not something to freeze in carbonite and write tests for.

I will often write unit tests just like with regular Clojure code and those get tested reactively in a separate tab using shadow-cljs, but that is because the expected input and output of a function rarely changes.

1 Like

We’ve been using Cypress (https://www.cypress.io/) at work recently, and I have to say that it is by far the best web-testing framework I’ve ever used. It is easy to setup and has batteries included. No extra setup for headless browsers / webdriver or anything because of its usage of Electron (although it can remote control other browsers as well). And it is quite easy to write the tests because of the debugging tools included (using a dom inspector to help finding css selectors to elements). I’ve struggled quite a bit with timing issues with Selenium in the past, but with Cypress this has been non-existent so far.

In regards to strategy I try to keep the web tests to a minimum. Preferably no more than a single test per feature. I use them more as smoke tests for the system than anything else.

3 Likes

Thanks for the insight.

It is mostly to make sure certain critical user flows are not hitting regressions mostly. I agree that these are hard to change. I actually have no idea how much of a pain its going to be really. I will have to try it out and see.

We’ve been using Cypress (https://www.cypress.io/ ) at work recently

Wow this looks really nice! Thanks for the suggestion. I will give it a shot and see how it goes.

For me, I write CLJS tests for things like “validations” and other state-change features, and for user interaction I also go with Selenium.

If you don’t really need to stay on Clojure-land all the time, I recommend Ruby with Capybara. It also uses Selenium, but it have some helper functions like Capybara.fill_in 'User', with: 'Name' that do lots of interesting things:

  1. Tries to find the element by name or ID
  2. If that fails, try to find a label with that that content, and go to the input linked to that label
  3. Waits if these are not present yet

It’s by far the best way to test frontend for me, because it also tests accessibility: if it’s not “testable”, it’s probably not “accessible” also. But I agree that’s not always that simple to mix another language on the stack…

I am not knowledgeable at all about frontends, but the lead (haskell) developer of quickstrom is top-notch. It seems to be based on property-based testing, maybe worthy of interest?

At the moment we do not have any automated frontend tests. From my previous projects I know how brittle they are. Back then I also developed a set of functions to abstract certain steps (login, register etc.) and the operation of UI elements (date picker etc.), so that the tests become more maintainable.

Recently, I wondered if machine learning have added some major improvements to the field of automated web testing in the recent years. I found a few services like:

There are many interesting ideas how machine learning can help to self-heal broken tests or visually compare the UI with previous test runs.

I tried a few services but non of them offered a significant better experience than writing selenium tests. Therefore I probably will use GitHub - igrishaev/etaoin: Pure Clojure Webdriver protocol implementation to write tests for selenium and use https://saucelabs.com/ to execute them as cross-browser testing.