What is the correct way to test that error message is observed?
Aside:
This arose in the course of a different issue, but I thought best to isolate this specific question: the correct way to test a message that is raised by falling through to a generic definition.
I’ll have to dig into world_age to fully appreciate what deeper testing this allows… on face value, it appears that approach would not be testing the code satisfied some (human) visible requirement.
For example: In one variation of the approach I outlined I discovered a typo in the source code for one of the methods/functions. This was only exposed by having the ‘correct’ error message defined in the test case.
Keep in mind that the message (“no method matching…”) is not part of the exception itself, it’s part of the logic that prints the exception, i.e. showerror. If you want to test that a reasonable error message is displayed to your users, then test the error message. If you want to test that your methods are correctly defined, just test the exception.
I would like to suggest an improvement to the code you posted above. In its current form, if the test fails, it doesn’t print what operation made it fail:
Test Failed at /.../error_message.jl:13
Expression: err isa Exception
Evaluated: nothing isa Exception
ERROR: LoadError: There was an error during testing
This can be quite annoying, for example if it happens on a build server, and the test informs you that something failed but not what. I would suggest something like this:
for op in opcoll
e = try @eval $op() catch ex; ex; end
e isa MethodError || throw(AssertionError("$op() should not be defined"))
end
Which tells you:
ERROR: LoadError: AssertionError: nobs() should not be defined
Alternatively, if you want to test the message itself:
for op in opcoll
e = try @eval $op() catch ex; ex; end
occursin("no method matching $op()", sprint(showerror, e)) ||
throw(AssertionError("$op() should not be defined"))
end