Paradox

Paradox

Testing is an important part of any modern piece of software. But writing tests can quickly become an exercise in frustration, with tons of repeated code, duplicate setup routines, and cumbersome assertions. ExUnit, Elixir’s testing framework, is ultimately just pure Elixir, and so we can extend it using more elixir features. Isolated setup units that can be mixed and matched, configuration via tags, and custom assertions are trivial to add to a test suite, and can save tons of developer headache

Showing Posts 17 to 8

lud

lud

This is my current command to run the tests:

mix test --failed --max-failures 1 --seed $(odo -c _build/seed.txt) && \
mix test --stale  --max-failures 1 --seed $(odo -c _build/seed.txt) && \
odo _build/seed.txt

odo is a simple counter that reads or increments a number from a file.

So what is does is:

  • as long as I have a failing test, it will only run that test, thanks to the seed
  • when this test passes, it will now fail repeatedly on the next failing test
  • when all my previously failing tests pass, it will run all the stale tests. If one of them fails, the loop will start over.
  • if everything passes, we increment the seed to preserve a minimum of entropy like designed in ExUnit.

A simple shortcut for vscode:

  {
    "key": "ctrl+alt+u",
    "command": "workbench.action.terminal.sendSequence",
    "args": {
      "text": "mix test --failed --max-failures 1 --seed $(odo -c _build/seed.txt) && mix test --stale --max-failures 1 --seed $(odo -c _build/seed.txt) && odo _build/seed.txt\n"
    }
  },
trisolaran

trisolaran

Thanks. I asked because I’ve been writing this kind of helpers for at least a couple of years now and I never thought about writing them as macros, so I was wondering if there was a deeper reason behind your choice.

Paradox

Paradox OP

Thats mostly out of a bit of laziness, to allow the module that’s defining the macros to not have to import the parts of ExUnit that does the assertions.

If you wanted to do them as pure functions, you’d have to import ExUnit.Assertions into the module you’re defining them in.

I’d written up an explanation on what I thought was the right answer, and even went to update the blog post to show you could use functions, but thought I should test it, and then on the first run of the test suite, got errors from no function named assert. So there you have it!

trisolaran

trisolaran

Speaking of macros, I’m curious why you use macros for your helpers instead of regular functions?

Paradox

Paradox OP

Yeah that one is pretty cute; works by passing around a tuple of the things you’d need for each one. Pretty clean way of doing it without much macro abuse

sodapopcan

sodapopcan

Ya I get it. I sometimes feel my tests get a little verbose with lv or view piping into everything so it wouldn’t take much to get me to buy into this if I were on a team that wanted to.! I was really interested in this project. I still am but I got really distracted by work and it just kind of slipped my mind.

Paradox

Paradox OP

It was mostly to reduce the large maintenance burden of writing

view |> element("button", "Create post") |> render_click()

everywhere (over 10k tests!)

We defined two versions, however, one that does “magic” and one that takes the view in as its first argument, so you can override as you need.

Looking at the calls, we use the explicit one in a couple places, and the implicit one everywhere else.

And its noted in the documentation using an Admonition/Nutrition facts thing, and failure to have a view variable set causes a compile error.

sodapopcan

sodapopcan

Hey if a team can decide and stick to it that’s totally cool! I’m solo right now but don’t trust myself not to die by a thousand cuts :sweat_smile: I also want less to document and explain if anyone else ever joins the project so I’ve been avoiding even the most seemingly innocuous things.

Paradox

Paradox OP

We use some custom click/form fill macros that pull it out of the current space at my current job, but my team is a two man team, and we both agreed that it was better than having to write lv all over the place.

All our assertions still require you to pass a html by hand.

sodapopcan

sodapopcan

Yep—it crossed my mind to do that and considered mentioning it here but didn’t want to give anyone any ideas :sweat_smile: I think it’s a bit gnarly and of course it stays pipeable if you directly accept the dependency. I’ve abandon every idea I’ve had like this after shooting myself in the foot with Ruby over the years. You technically don’t even need a macro to make it work as it is, but it’s a little bit simpler sorta.

Where Next? Top

Trending in Blog Posts Top

bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New
pckrishnadas88
Hey everyone! :waving_hand: I’ve published Part 7 of the Building Distributed Systems in Elixir series, where we build core distributed ...
New
mudasobwa
So, instead of wasting my afternoon arguing with anonymous handles on X, I turned to my trusty, soulless assistant and said: “Listen, ple...
New
zorn
An educational side project in Elixir, Phoenix, and Tauri. I share what I learned while wiring Automerge into the BEAM, including how I s...
New
abreujp
New article: Elixir Project Structure — From mix new to a Growing Codebase I’ve published a new article in my Elixir learning series on d...
New
nathanl
Process labels are useful for visualization and debugging. Here’s why you should use them.
New
mudasobwa
Somewhere, right now, a senior engineer is on the verge of a nervous breakdown because his company will not let him switch from Claude to...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews