Test.@test_throws
cannot deal with error values which have fields which are not comparable with ==
, eg NaN
. MWE:
using Test
struct MyException{T}
value::T
end
f(x) = throw(MyException(x))
@test_throws MyException(NaN) f(NaN)
gives
julia> @test_throws MyException(NaN) f(NaN)
Test Failed at REPL[65]:1
Expression: f(NaN)
Expected: MyException{Float64}(NaN)
Thrown: MyException{Float64}(NaN)
ERROR: There was an error during testing
julia> VERSION
v"1.2.0-DEV.396"
Perhaps
allow equality by ==
or ===
?
let the user specify a closure for checking, eg
@test_throws e -> (e isa MyException && e.value === NaN) f(NaN)
I think it would be more readable to have a macro that returns the exception.
e = @get_exception f(NaN)
@test e === MyException(NaN)
See also here.
I think, it would make sense to use isequal
instead of ==
when comparing the fields of the exception.
That would cover the floating point and the missing
cases correctly.
As a tiny nitpick, shouldn't we rather typeof(x)==typeof(y) && isequal(x, y)
?
This looks somehow wrong in the context of unit tests:
struct MyException2
value
end
f(x) = throw(MyException2(x))
@test_throws MyException2(1) f(1.0)
Test Passed
Especially since we do compare types of the exceptions themselves, so MyException{T}
does get types compared.
I would say the test passing is correct, because MyException2(1) == MyException2(1.0)
with the standard implementation of ==
for structs.
There is no general notion of equality, especially in the context of unit tests, where only the programmer has enough context to decide how exacting the comparison should be.
Picking a reasonable default like isequal
is useful, but I think the best solution would be allowing either a closure, or perhaps the @get_exception
solution above.
The proposed bug-fix (for your original issue) checks for the type of the thrown exception and the equality of all fields of the exception (if any). That should be sufficient for the usual complexity of exception objects.
If it is necessary to supply an anonymous function or other means to have more control about how the check of the exception has to be done, IMHO that is a new feature, which deserves an extra PR.
Most helpful comment
I think, it would make sense to use
isequal
instead of==
when comparing the fields of the exception.https://github.com/JuliaLang/julia/blob/5a4191d5607f957b0d02f62fd588b11a215c638f/stdlib/Test/src/Test.jl#L587
That would cover the floating point and the
missing
cases correctly.