# @testset expands all macros \*before\* executing the generated code

**URL:** https://discourse.julialang.org/t/testset-expands-all-macros-before-executing-the-generated-code/102197
**Category:** General Usage
**Tags:** testing, macros, metaprogramming
**Created:** [July 28, 2023, 2:19pm UTC](https://discourse.julialang.org/t/testset-expands-all-macros-before-executing-the-generated-code/102197 "2023-07-28T14:19:21Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![iago-lito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iago-lito/32/31924_2.png) [@iago-lito](https://discourse.julialang.org/u/iago-lito)
#### Post date: [July 28, 2023, 2:19pm UTC](https://discourse.julialang.org/t/testset-expands-all-macros-before-executing-the-generated-code/102197/1 "2023-07-28T14:19:21Z")

</div>

Hello community. I’ve just spent hours confusingly revolving around the following quirk.

Given this code in my package:

```julia
macro a()
    println("expand a")
    :(println("exec a"))
end

macro b()
    println("expand b")
    :(println("exec b"))
end

```

And this user code:

```julia
println("invoke a")
@a
println("invoke b")
@b

```

I expect the following behaviour (based on the current REPL behaviour):

```julia
invoke a
expand a
exec a
invoke b
expand b
exec b

```

However, this is what happens when I automate the test:

```julia
using Test
@testset "" begin
    println("invoke a")
    @a
    println("invoke b")
    @b
end

```

```julia
expand a # !
expand b # !
invoke a
exec a
invoke b
exec b

```

1. Is that expected behaviour?
2. Is that somehow configurable?
3. Can I rely on the REPL behaviour (_i.e._ macros being expanded _on invocation_) and just work around `@testset` for my tests, or should I not assume that Julia upholds any guarantee regarding macros expansion time?

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [July 28, 2023, 2:34pm UTC](https://discourse.julialang.org/t/testset-expands-all-macros-before-executing-the-generated-code/102197/2 "2023-07-28T14:34:59Z")

</div>

> [@iago-lito](#):
>
> Is that expected behaviour?

Yes, macros are expanded before the expanded code is executed. They are expanded outside-in (you can check with `Base.@macroexpand1`, if I’m not mistaken).

> [@iago-lito](#):
>
> Is that somehow configurable?

No. Macros are an AST transform.

> [@iago-lito](#):
>
> Can I rely on the REPL behaviour (_i.e._ macros being expanded _on invocation_) and just work around `@testset` for my tests, or should I not assume that Julia upholds any guarantee regarding macros expansion time?

I’m not sure I follow - when a macro is expanded, the code inside the macro building the expression (even if not contributing to the returned expression) still has to run.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [July 28, 2023, 6:43pm UTC](https://discourse.julialang.org/t/testset-expands-all-macros-before-executing-the-generated-code/102197/3 "2023-07-28T18:43:36Z")

</div>

It’s not particular to `@testset`, it’s because a `begin` block is a compound expression. The REPL reads one complete expression, not line, at a time; the `begin` block is only considered complete at the `end`.

```julia
julia> begin
           println("invoke a")
           @a
           println("invoke b")
           @b
       end
expand a
expand b
invoke a
exec a
invoke b
exec b

```

---

<div class="post-metadata">

### Author: ![iago-lito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iago-lito/32/31924_2.png) [@iago-lito](https://discourse.julialang.org/u/iago-lito)
#### Post date: [July 31, 2023, 8:52am UTC](https://discourse.julialang.org/t/testset-expands-all-macros-before-executing-the-generated-code/102197/4 "2023-07-31T08:52:15Z")

</div>

Thank you for feedback @Sukera @Benny 🙂 IIUC what I’m observing is rather related to how julia parser / expansion works, and also happens without @testset with plain `begin/end` blocks.

I guess I just need to be careful not to rely on the exact nesting order between my macro expansions and actual generated code execution, because I cannot enforce that they won’t be invoked within macros or `begin/end` blocks downstream ^ ^"
