Wrapping tests involving eval in @testset

I often get into trouble wrapping unit tests involving macros or eval in @testset. Can someone explain why the first example works but the second fails?

    x = 5
    eval(quote
         @test x == 5
         end
         )
@testset "tests" begin
    y = 5
    eval(quote
         @test y == 5
         end
         )
end

tests: Error During Test at REPL[552]:4
  Test threw exception
  Expression: y == 5
  UndefVarError: y not defined
  Stacktrace:
   [1] top-level scope at REPL[552]:4
   [2] eval at ./boot.jl:319 [inlined]
   [3] eval(::Expr) at ./client.jl:393
   [4] macro expansion at ./REPL[552]:3 [inlined]
   [5] macro expansion at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:1083 [inlined]
   [6] top-level scope at ./REPL[552]:2

Running on julia 1.0.5

eval() evaluates the expression in the global scope. In your first example you defined x as global. In the second y is local to the testset.

https://docs.julialang.org/en/v1/base/base/#Base.MainInclude.eval

If you changed it to:

@testset "tests" begin
    global y = 5
    eval(quote
         @test y == 5
         end
         )
end

It will work, but Iā€™m not sure that is what you want.

1 Like

That clears up my confusion. Many thanks.