elixir

Test Your Elixir Package Against Different Versions of Its Dependencies

Marcelo Dominguez avatar

Marcelo Dominguez

- March 20, 2025

TL;DR: Your package depends on other packages, and their updates can break your package without you realizing it. We published blend, an elixir package to make testing against multiple versions of dependencies fast and simple. Check out blend_example to see it in action, with two open pull requests showing exactly how to integrate it into your package.

Why should you care?

If you create or maintain an Elixir package, chances are it's built on top of other open-source libraries. You can see this clearly in your mix.exs dependencies. Take surface packages as an example:

1defp deps do
2  [
3    ...
4    {:phoenix_live_view, "~> 0.19.0 or ~> 0.20.10 or ~> 1.0"},
5    ...
6  ]
7end
8

This means that if your app uses surface, it will depend on a version of phoenix_live_view that surface declares as supported.

Surface has extensive tests to catch regressions and ensure features work correctly. But what version of phoenix_live_view it is used when those tests are run?

When you run mix test, your tests uses the dependencies as exactly defined in in mix.lock. For example:

1"phoenix_live_view": {:hex, :phoenix_live_view, "1.0.4", ...}

So, as Surface evolves, new features, bug fixes and refactors are implemented in surface source code, how do you know it still works with 0.19.x or 0.20.x?

You don’t. 😞

A great package stays great by multiple reasons but avoiding regressions or having as few bugs as possible is one of them. The sooner you catch issues, the better, the feedback loop is crucial.

Consider these real-world examples:

  • Oban issue #1041
  • Money issue #213
  • Both potentially could have been avoided.

    How to test against multiple versions of dependencies

    Introducing Blend

    We built blend to make it as easy as possible to test against multiple dependency versions without manual mix.lock juggling. Blend is a development-only tool, meaning it won’t bloat your production release.

    How blend started?

    While developing candlex (an Nx backend), we realized that testing against different versions of Nx and Bumblebee was a real pain. We started building a solution to simplify this process, and then we realized this was a problem the broader community could benefit from.

    At first, we wondered whether this wasn’t a common practice because it didn’t feel like a real problem or if the problem was real but we were just missing the right tools to solve it easily.

    We believe it’s the latter, so we decided to extract blend into its own package.

    With blend, you can define a test matrix covering different versions of Elixir, Erlang, and your dependencies using any CI provider.

    Projects already using it:

    How can you start?

    Go check out blend README. We also created blend_example to demonstrate how easy is to integrate blend into an existing package. Check out these two different approaches PRs:

    PR #1 - Add Blend overriding your mix.lock

    PR #2 - Add Blend with BLEND env var configuration

    Let us know how it works for you!

    mimiquate petmimiquate pet