marcandre

marcandre

How to have uncaptured logger calls generate failures in ExUnit?

I’d like that any test that generates uncaptured log entries fails.

Is there an easy way to do this?

Otherwise, would adding a custom Logger backend work, i.e. would it not be called if there’s a @capture_log tag or if the test is wrapped in capture_log(...)?

Most Liked

Sebb

Sebb

I was in the same situation, that I wanted to include logging in the tests. I ended up writing a little macro that gets some meta-data from __CALLER__ and generates log-tuples

assert [{:logger, :error, {4711, %{file: _, line: _}}}] = error(4711)
assert [{:logger, :warning, {'test', %{file: _, line: _}}}] = warning('test')
assert [{:logger, :debug, {[a: 1, b: 2], %{file: _, line: _}}}] = debug([a: 1, b: 2])

The advantage over capture_log is, that you can use structured logging while capture_log can only use the console backend. Also it’s absolutely pure (if you are strict and see logging as impure) so there are no problems with async. But you have to handle the log-data the core produces somehow in the shell (and do the real logging).

josevalim

josevalim

Creator of Elixir

There is no such feature at the moment. It would need to be added to Elixir. But keep in mind that, given your tests run concurrently, this could cause Heisenfailures as one test could incorrectly capture the logs of another test and not fail when it should fail (which is ok, it would not be ok to fail when it should not have).

marcandre

marcandre

Here’s are examples of captured/uncaptured entries:

test "this is captured" do
  assert capture_log(fn ->
    Logger.warn("example")
  end) =~ "example"
end

@tag capture_log
test "this is captured too" do
  Logger.warn("example")
end

test "this is not captured and should fail" do
  Logger.warn("example")
end
josevalim

josevalim

Creator of Elixir

Yeah, we could support a @tag :assert_no_log.

josevalim

josevalim

Creator of Elixir

This is where we check for capture log tag: elixir/lib/ex_unit/lib/ex_unit/runner.ex at main · elixir-lang/elixir · GitHub

We probably want to make it a tri-state: :capture, :none, :assert. And then fail the test if it passes but has a log in asset mode.

Where Next?

Popular in Questions Top

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
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

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
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
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement