Hi!
I decided to create my very first package. This “baby” package contains only one function (I give an example):
using Plots
using Distributions
function easy(x::Vector{Float64})
a = print("The mean is:", mean(x))
b = print("\nThe variance is:", var(x))
c = plot(x)
end
The user gives
a=[1,5,4,7.6]
easy(a)
Then, the function prints the mean of a, the variance of a and a simple plot of a. I get some functions from the Distributions.jl package and the plot from the Plots.jl package. I have followed all the needed steps to create my package and it’s time to test it.
I found a simple function test example:
using MyPackage
using Test
@testset "MyPackage" begin
x = 2
y = 2
@test MyPackage.sum(x,y) = = 4
end
This is true, so the test is passed. In this case, it’s logical to test this.
In my case, I didn’t create any mathematical or new complex structured functions to test; only a function that prints some statistical results and an output of a plot (this might help a student).
In my case, though, what do I need to test my function? Does it make any sense?
3 Likes
I don’t know of a way to do this with the standard library, but there are two packages that can help by capturing the output of your function to a string which you can then test against an expected result:
https://github.com/JuliaDocs/IOCapture.jl
https://github.com/JuliaIO/Suppressor.jl
2 Likes
Thank you! But what do I test here? My easy() function or every print separately? The type of easy(a) is Plots.Plot{Plots.GRBackend} because the prints are only prints. See the screenshot below:
It is probably worth looking at the tests for plots.jl https://github.com/JuliaPlots/Plots.jl/tree/master/test to see what you can query about a plot once it has been created. Then you can decide which of those attributes are important to your function and ensure they match the expected value.
3 Likes
If you return the values in the function, can can test them. Here is an example:
function easy(x::Vector{Float64})
μ = mean(x)
σ = std(x)
print("The mean is:", μ)
print("\nThe variance is:", σ)
c = plot(x)
return μ,σ,c
end
x = [1.0,2.0,3.0]
μ,σ,p = easy(x)
@test μ ≈ 2.0
@test σ ≈ 1.0
@test p[1][1][:y] == x
I’m not sure how to test the print statements and plot further.
3 Likes
As contradict suggested, you can test the print statement like so:
using IOCapture
c = IOCapture.capture() do
easy(x)
end
@test c.output == "The mean is:2.0\nThe variance is:1.0"
4 Likes
Thanks to both of you! It worked like a charm!
Can’t you just use redirect_stdout
for this?
Extra credit: Functions that print things to stdout typically define two methods like this
function myfun(io::IO, x)
println(io, 3x)
end
myfun(x) = myfun(stdout, x)
Testing this function is easier, because we can use our own IOBuffer
instead of stdout.
4 Likes