Suppress stderr while running Mix test in Elixir

I am working with several external processes in my application. During the tests, the stderr output from several of them is dumped in a row with my test messages and results. I can do it:

mix test --trace 2> error.log


However, when I do this, I lose all my beautiful colors. Also, some Elixir bugs still appear, though not all (which is good for me).

Is there a better way to suppress errors in external programs without affecting the mixing output? Is this even a good idea?

Or are my tests actually not interacting with real command line utilities? I ask because at that moment I honestly no longer understand what I am testing.


Below is a simplified function and test to better illustrate the concept.


@doc "Function takes a pre-routing rule as a string and adds it with iptables"
def addrule(pre_routing_rule)
  %Porcelain.Result{out: _output, status: status} ="sudo iptables -t nat -A #{pre_routing_rule}")



test "Removing a non-existent rule fails" do 
  assert {:error, :eiptables} == Rules.remove("PREROUTING -p tcp --dport 9080 -j DNAT --to-destination")


This test is going well. However, the inline with test messages will also output iptables: No chain/target/match by that name.

. The exact position of the message is also unpredictable, and in droves these messages make the test information difficult to read. Then I redirect stderr and for some reason I lose the color coding, which also makes it difficult to track the test results.


source to share

2 answers

I would suggest in general that you decide how to deal with stderr in your system calls. What happens is that the test environment catches stdout, but not stderr.

You can change how stderr is processed the first time you call Porcelain. See

Porcelain API Documents



I think you should suppress these error messages in the place where you call the command line utilities, for example using the same method as in the question.

The lack of colors is due to the way Elixir detects ANSI :

[ANSI Support] defaults to false unless Elixir can detect at startup that both stdout and stderr are terminals.



All Articles