Julia: comparison of NaN for @test_throws

Created on 1 Mar 2019  路  6Comments  路  Source: JuliaLang/julia

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

  1. allow equality by == or ===?

  2. let the user specify a closure for checking, eg

@test_throws e -> (e isa MyException && e.value === NaN) f(NaN)

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.

All 6 comments

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.

https://github.com/JuliaLang/julia/blob/5a4191d5607f957b0d02f62fd588b11a215c638f/stdlib/Test/src/Test.jl#L587

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

musm picture musm  路  3Comments

wilburtownsend picture wilburtownsend  路  3Comments

Keno picture Keno  路  3Comments

felixrehren picture felixrehren  路  3Comments

dpsanders picture dpsanders  路  3Comments