Test for a warning

519 views
Skip to first unread message

Paweł Biernat

unread,
Jun 20, 2014, 8:27:55 AM6/20/14
to julia...@googlegroups.com
I would like to write a test case verifying that a function call results in a warning.  I have seen that there are tests for exceptions, but I was unable to find a test for warining in the docs.

Paweł Biernat

unread,
Jun 20, 2014, 8:49:07 AM6/20/14
to julia...@googlegroups.com
A little example

using Base.Test

function f(x)
   
if x < 0
        warn
("x should be non-negative")
   
end
   
return x
end

@test_warning f(-1)  #this is the test I am looking for

Stefan Karpinski

unread,
Jun 20, 2014, 10:23:26 AM6/20/14
to Julia Users
There is currently no way to do this.

Jameson Nash

unread,
Jun 20, 2014, 10:36:44 AM6/20/14
to julia...@googlegroups.com
You could redirect_stderr and test for content written

Laszlo Hars

unread,
Jun 20, 2014, 4:35:51 PM6/20/14
to julia...@googlegroups.com
Could someone help with redirecting stderr? For example, the following code does not get the error message shown in the Julia console in Windows 7, Julia Version 0.3.0-prerelease+3789:
~~~
stderr_orig = STDERR
rd, wr = redirect_stderr()
1^-1
close(wr)
eof(rd)
close(rd)
out = readall(rd)
redirect_stderr(stderr_orig)
~~~

Mike Innes

unread,
Jun 20, 2014, 4:47:28 PM6/20/14
to julia...@googlegroups.com
function with_out_str(f::Function)
  orig_stdout = STDOUT
  rd, wr = redirect_stdout()
  f()
  redirect_stdout(orig_stdout)
  return readavailable(rd)
end

macro with_out_str(expr)
  :(with_out_str(()->$expr)) |> esc
end

You can use this as

@with_out_str begin
  ... code ...
end

But I think you'll need to change "stdout" to "stderr" in the above definition to capture warnings.

Laszlo Hars

unread,
Jun 20, 2014, 5:29:07 PM6/20/14
to julia...@googlegroups.com
I am confused: I can change all the "out"s to "err"s, but what variable will contain the error message to be inspected? The error messages seem to only appear in the console, nowhere else.

Leah Hanson

unread,
Jun 20, 2014, 5:36:44 PM6/20/14
to julia...@googlegroups.com
~~~
errormsg = @with_out_str begin
  ... code ...
end
~~~

should put the error message into errormsg.

-- Leah

Mike Innes

unread,
Jun 20, 2014, 5:40:03 PM6/20/14
to julia...@googlegroups.com
The macro expression itself will return the output string. So if you type it into a repl you'll get something like

julia> @with_err_str warn("foo")
"\e[1m\e[31mWARNING: foo\n\e[0m"

If you want to capture that string you'd just assign it to a variable:

julia> err = @with_err_str warn("foo");

One thing to be careful of is that those ANSI codes may not be included when running the tests.

Jameson Nash

unread,
Jun 20, 2014, 5:42:15 PM6/20/14
to julia...@googlegroups.com
Your code looks generally fine, except that you close the read end before actually reading the data. Also, you don't catch the error, so it aborts execution early. Try wrapping you user code in a try/catch block. 

(Ps can we please get rid of readavailable before 0.3. Also, this is why the function form of redirect_stdio was in my list of features to include in 0.3)

Laszlo Hars

unread,
Jun 20, 2014, 5:48:59 PM6/20/14
to julia...@googlegroups.com
I must be doing something stupid. This is what I typed into the console:
~~~
function er(f::Function)
  orig_stderr = STDERR
  rd, wr = redirect_stderr()
  f()
  redirect_stderr(orig_stderr)
  return readavailable(rd)
end

macro er(expr)
  :(er(()->$expr)) |> esc
end

err = @er begin 1^-1 end

err
~~~
I only get:
ERROR: err not defined

Could it be some problem with the Windows console or the new REPL? (I coded similar functions a couple of months ago, and they did work. Not anymore)

Laszlo Hars

unread,
Jun 21, 2014, 12:51:49 PM6/21/14
to julia...@googlegroups.com
...can someone at least verify that the 0.3.0 Julia console output in Windows is not written to STDOUT, and error messages are not written to STDERR? (The results of print() do appear on STDOUT)

Jameson Nash

unread,
Jun 21, 2014, 1:13:51 PM6/21/14
to julia...@googlegroups.com

julia> begin

       stderr_orig = STDERR

       rd, wr = redirect_stderr()

       try

       warn("HI")

       finally

       redirect_stderr(stderr_orig)

       close(wr)

       out = readall(rd)

       println(length(out),out)

       end

       end

25WARNING: HI


in you example, code, throwing an error does not cause anything to be written to stdout, it is a break in control flow that gets caught by the REPL, skipping execution of all of the rest of your code.


Note that the calls to both redirect_stderr and close are necessary before readall, because we have multiple handles to the write end of the pipe, and need to close all of them before the read end will receive the EOF signal

Laszlo Hars

unread,
Jun 21, 2014, 2:25:06 PM6/21/14
to julia...@googlegroups.com
Thanks, Jameson. That explains, why I cannot catch errors, only warnings. That is, the following code will not (and I verified, it does not) work.
~~~
begin
stderr_orig = STDERR
rd, wr = redirect_stderr()
try
error("HI") ###
finally
redirect_stderr(stderr_orig)
close(wr)
out = readall(rd)
println(length(out),out)
end
end
~~~

Is there a trick to catch the error message and return it in a variable?

Laszlo Hars

unread,
Jun 21, 2014, 3:44:03 PM6/21/14
to julia...@googlegroups.com
...furthermore: I naively thought the same code would capture the console output in a variable. It does not. What am I still missing?
~~~
begin
stdout_orig = STDOUT
rd, wr = redirect_stdout()
try
1+2
finally
redirect_stdout(stdout_orig)
close(wr)
out = readall(rd)
println((length(out),out))
end
end
~~~

RESULT:
(0,"")
3

That is, the "out" variable is empty, but the result of 1+2, "3" is magically printed in the console window. Again, a very similar piece of code used to capture the console output a couple months ago with the then current 0.3.0 nightly.

Laszlo Hars

unread,
Jun 21, 2014, 4:45:29 PM6/21/14
to julia...@googlegroups.com
...and this is what I meant by saying that print() does produce data on STDOUT (but regular console output does not):
~~~
begin
stdout_orig = STDOUT
rd, wr = redirect_stdout()
print(1+2)
redirect_stdout(stdout_orig)
close(wr)
out = readall(rd)
println((length(out),out))
end
~~~

RESULT (as expected):
(1,"3")

Laszlo Hars

unread,
Jun 23, 2014, 1:59:10 PM6/23/14
to julia...@googlegroups.com
We could summarize our finding so far about the Julia console output
~ For Windows, with the latest nightly 0.3.0 Julia version

- Warnings are written to STDERR, they can easily be redirected, captured to a variable
- Error messages might or might not get written to STDERR, but they cannot be captured to a variable, because the code execution aborts beforehand [bad]
-- I also failed to get error messages via another thread redirecting STDERR
- The output of print() is written to STDOUT, which can be redirected and captured. This does not seem to matter, because we can directly print to a pipe
- The console output is not written to STDOUT as if it were printed: it cannot be captured to a variable [bad]

Could someone verify these? Especially the last bullet point looks suspect.

I'd like to find workarounds for error messages and regular console output. We can then log them in files, or pass them to other applications via the clipboard.

Reply all
Reply to author
Forward
0 new messages