Is there any convenient way to unit test whether a specific method is called?
The context is ThreadedSparseArrays.jl, that adds threading for sparse*dense multiplications.
I would like to make a unit test to check that a multiplication: A*B
ends up calling the correct mul!
method down the line.
Code coverage?
With code coverage you see whether a line of your package was hit at all during the tests, but you don't see the code path
That's a good point! Don't make it harder than it is. :grinning_face_with_smiling_eyes::grinning_face_with_smiling_eyes:
Actually, I couldn't help but making it a bit harder. :wink: Because not everyone really pays attention to read coverage changes, it might be covered by some test code but not in every situation I want it to, and it's nice to get a clear error message.
So I exploit that the function I want to check will throw an Exception
for incorrect matrix sizes and check which function and file the exception is thrown from.
With this:
function match_exception(f, ::Type{T}=DimensionMismatch, func=:mul!, path="ThreadedSparseArrays.jl") where T
try
f()
catch ex
st = stacktrace(catch_backtrace())[1]
p = splitpath(path)
p2 = splitpath(string(st.file))
return ex isa T && st.func == func && p==p2[max(1,end-length(p)+1):end]
end
false
end
I can test it like this:
A = ThreadedSparseMatrixCSC(spzeros(2,3))
B = zeros(4,1)
@test match_exception(()->A*B)
@test match_exception(()->A'B)
...
I'm no expert and I mostly read these threads to learn, but one thing I've read lately is that try/catch
is expensive.
Edit. I probably read it there: https://discourse.julialang.org/t/is-there-a-better-way-to-do-error-handling-on-julia-than-try-catch/21716/6
I think you are right that it can be expensive, and I wouldn't use throw
in performance critical code like an inner loop. But this is just for a couple of unit tests so it should be fine. And the code that might throw the exception needs to be there because we want the exact same behavior as the corresponding methods in SparseArrays
.
Last updated: Nov 06 2024 at 04:40 UTC