# Skipping a whole \`@testset\`?

**URL:** https://discourse.julialang.org/t/skipping-a-whole-testset/65006
**Category:** General Usage
**Tags:** testing
**Created:** [July 20, 2021, 9:33pm UTC](https://discourse.julialang.org/t/skipping-a-whole-testset/65006 "2021-07-20T21:33:30Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![johnomotani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnomotani/32/26753_2.png) [@johnomotani](https://discourse.julialang.org/u/johnomotani)
#### Post date: [July 20, 2021, 9:33pm UTC](https://discourse.julialang.org/t/skipping-a-whole-testset/65006/1 "2021-07-20T21:33:30Z")

</div>

I have a bunch of similar `@testset`s, and I know that some of them currently fail, and will do so until some upgrades are made to my package. For skipping single tests, there’s `@test_skip` or `@test_broken`, but is there a nice way to skip a whole `@testset`? I don’t want to alter the individual `@test` calls because they’re inside a function that’s called in `@testset`s that pass (and I don’t want to waste time running stuff that I know will fail). Putting `@test_skip @testset ...` sort of works: the `@testset`s are not run, and some ‘Broken’ entries appear in the output, but it would be nice if, for example, the `@testset`s’ names would still appear in verbose output, but highlighted and marked as broken. I guess a `skip=true` optional argument to `@testset` could do this?

Edit: even better than a `skip=true` argument would be `skip="foobar"` where the string can give a reason the test is skipped, which could be printed beside the `@testset`’s name in the summary.

---

<div class="post-metadata">

### Author: ![johnomotani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnomotani/32/26753_2.png) [@johnomotani](https://discourse.julialang.org/u/johnomotani)
#### Post date: [July 20, 2021, 10:02pm UTC](https://discourse.julialang.org/t/skipping-a-whole-testset/65006/2 "2021-07-20T22:02:16Z")

</div>

see also [Standard ways to run common commands - #12 by djsegal](https://discourse.julialang.org/t/standard-ways-to-run-common-commands/154/12)

PS sorry I missed that thread before opening this one - I made the mistake of searching for @testset, which apparently looks for posts by a user named @testset rather than posts mentioning the macro…

---

<div class="post-metadata">

### Author: ![Satvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/satvik/32/20486_2.png) [@Satvik](https://discourse.julialang.org/u/Satvik)
#### Post date: [July 20, 2021, 10:23pm UTC](https://discourse.julialang.org/t/skipping-a-whole-testset/65006/3 "2021-07-20T22:23:26Z")

</div>

I ran into this problem, so I wrote a small macro:

```julia
s = ArgParseSettings()
@add_arg_table! s begin
    "--include_tests"
    arg_type = String
    required = false
    action = "store_arg"
    nargs = '*'
end

parsed_args = parse_args(s)
include_tests = Set(parsed_args["include_tests"])

macro test_if_included(expr::Expr)
  # For now, assume the expression is a macro followed by a string, e.g.
  # @timeit "name1" or @testset "name2"
  name = expr.args[3]
  if isempty(include_tests)
    esc(expr)
  elseif name in include_tests
    esc(expr)
  else
    nothing
  end
end

# Single test with @timeit
@test_if_included @timeit "name" begin ...

# Multiple tests with @testset
@test_if_included @testset "name" begin...

```

Then you can run it like so:

`using Pkg; Pkg.test(test_args=["--include_tests", "my_test_set"])`

---

<div class="post-metadata">

### Author: ![johnomotani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnomotani/32/26753_2.png) [@johnomotani](https://discourse.julialang.org/u/johnomotani)
#### Post date: [July 21, 2021, 7:21pm UTC](https://discourse.julialang.org/t/skipping-a-whole-testset/65006/4 "2021-07-21T19:21:26Z")

</div>

Thanks @Satvik, but I was aiming in particular at the case when some tests are ‘broken’, rather than wanting to switch between them interactively.

I spent a few hours learning that wrapping `@testset` in another macro isn’t possible (at least for someone with my limited knowledge of macros), see [Calling a macro from within a macro, revisited](https://discourse.julialang.org/t/calling-a-macro-from-within-a-macro-revisited/19680), [https://github.com/JuliaLang/julia/issues/37691](https://github.com/JuliaLang/julia/issues/37691), and [Nested macros and esc](https://discourse.julialang.org/t/nested-macros-and-esc/47857). After giving up on that, I ended up coming up with this macro that skips a testset and adds a `DefaultTestSet` with a dummy broken test so that it can show up in the summary:

```julia
import Test: Test, finish
using Test: DefaultTestSet, Broken
using Test: parse_testset_args

"""
Skip a testset

Use `@testset_skip` to replace `@testset` for some tests which should be skipped.

Usage
-----
Replace `@testset` with `@testset "reason"` where `"reason"` is a string saying why the
test should be skipped (which should come before the description string, if that is
present).
"""
macro testset_skip(args...)
    isempty(args) && error("No arguments to @testset_skip")
    length(args) < 2 && error("First argument to @testset_skip giving reason for "
                              * "skipping is required")

    skip_reason = args[1]

    desc, testsettype, options = parse_testset_args(args[2:end-1])

    ex = quote
        # record the reason for the skip in the description, and mark the tests as
        # broken, but don't run tests
        local ts = DefaultTestSet(string($desc, " - ", $skip_reason))
        push!(ts.results, Broken(:skipped, "skipped tests"))
        local ret = finish(ts)
        ret
    end

    return ex
end

```

I’d still vote for something like this as a feature of the standard-library `@testset` and `DefaultTestSet`.
