bmarkons

bmarkons

Failed tests summary at the end of mix test output

Hi,

I have one basic question.

Is there a way to get the list of failed tests at the end of mix test output? Do you have to come up with custom formatter or there is some flag?

Cheers

Most Liked

sodapopcan

sodapopcan

I use this custom formatter for our CI to get the failures summarized at the bottom. There is a small race condition in it which can cause an extra line or two at the end, but it does the job. I’ve only ever used with along with --trace so not sure what it looks like with anything else (probably much the same).

defmodule MyApp.Test.Formatter do
  @moduledoc """
  Adds test failures to the bottom of the test output.

  This is mostly only useful when run with `--trace`.

  Usage:

     $ mix test --trace --formatter MyApp.Test.Formatter
  """

  use GenServer

  @format_cols 80

  @doc false
  def init(opts) do
    {:ok, pid} = GenServer.start_link(ExUnit.CLIFormatter, opts)
    {:ok, %{cli_formatter: pid, failures: []}}
  end

  def handle_cast({:test_finished, %{state: {:failed, errors}} = test} = event, state) do
    GenServer.cast(state.cli_formatter, event)

    counter = length(state.failures) + 1

    error =
      ExUnit.Formatter.format_test_failure(test, errors, counter, @format_cols, &formatter/2)

    state = %{state | failures: [error | state.failures]}

    {:noreply, state}
  end

  def handle_cast({:suite_finished, _} = event, state) do
    GenServer.cast(state.cli_formatter, event)

    if Enum.any?(state.failures) do
      failures =
        state.failures
        |> Enum.reverse()
        |> Enum.join("\n")

      IO.puts("""

      #{String.duplicate("=", @format_cols)}

        Failures:

      #{failures}

      #{String.duplicate("=", @format_cols)}
      """)
    end

    {:noreply, state}
  end

  def handle_cast(event, state) do
    GenServer.cast(state.cli_formatter, event)

    {:noreply, state}
  end

  defp formatter(_key, value), do: value
end
dimitarvp

dimitarvp

I can’t answer your question directly – it’s been a long time since I last looked at test formatters – but one workaround is to just run mix test --failed afterwards, which will only run the tests that failed during the previous run.

If your concern is that you have too much test terminal output and that you’re finding it hard to track the output only of those that failed then maybe that command will help you.

bmarkons

bmarkons

Yes, that’s exactly my concern. Thanks for pointing me to mix test --failed. Unfortunately, it doesn’t help in case when failed test log is captured so you still have a lot of scrolling. Sometimes you just want to see the summary of failed tests - without investigating the log of the failed test.

PJUllrich

PJUllrich

Author of Building Table Views with Phoenix LiveView

I adapted this script a little to make it project-agnostic. It now fetches the manifest based on the Mix.Project.manifest_path()

# list_failed_tests.exs
manifest_path = Mix.Project.manifest_path() |> Path.join(".mix_test_failures")

if not File.exists?(manifest_path) do
  IO.puts("Can't find manifest file at #{manifest_path}")
  System.stop()
  Process.sleep(:infinity)
end

manifest_path
|> File.read!()
|> :erlang.binary_to_term()
|> elem(1)
|> Enum.group_by(fn {_, file} -> file end, fn {{_mod, name}, _file} -> name end)
|> Enum.each(fn {file, tests} ->
  IO.puts([
    IO.ANSI.red(),
    "Failures in #{file}:\n",
    Enum.map_join(tests, "\n", &"  * #{&1}"),
    "\n",
    IO.ANSI.reset()
  ])
end)

You can run it with MIX_ENV=test mix run list_failed_tests.exs

SofaKing18

SofaKing18

Hi there! I’ve same issue, that’s why I created simple library GitHub - balance-platform/ex_unit_summary: "Extension" for ExUnit

Feel free to use :slight_smile:

Where Next?

Popular in Questions Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New

We're in Beta

About us Mission Statement