# Using \[weakdeps\] and \[extensions\] to carry on a test module

**URL:** <https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247>\
**Category:** General Usage\
**Created:** [March 17, 2023, 2:15pm UTC](https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247 "2023-03-17T14:15:38Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [March 17, 2023, 2:15pm UTC](https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247/1 "2023-03-17T14:15:38Z")

</div>

For some packages it is useful to have a `TestModule` that defines functions to generate data, for example. It is many times interesting that these functions are available for the package user, particularly to provide examples of the package usage.

When the `TestModule` gets complex, and particularly when it depends on other packages that are not main deps of the package, carrying the module within the package becomes bad for loading times.

With the new `[weakdeps]` and `[extensions]` that may be solved, and I would like to hear thoughts about this possibility:

#### 1. Create the package `MyPackage`, containing a `TestModule`, which may depend on a heavy dependency:

```julia-auto
module MyPackage
...
include("./test/TestModule.jl")
end
# ./test/TestModule.jl
module TestModule
using Plots # heavy!
...
end

```

#### 2. Create a dummy `MyPackageTests` package, basically empty, and register it.

#### 3. Have the `Project.toml` of `MyPackage` to be:

```toml
name = "MyPackage"
version = "0.1.0"
uuid = "..."

[weakdeps]
MyPackageTests = "d38c429a-6771-53c6-b99e-75d170b6e991"

[extensions]
Plots = "MyPackageTests" # only loaded if MyPackageTests is loaded

[compat]
MyPackageTests = "0.1.0"
Plots = "0.6.2"

```

### Result:

One can develop `MyPackage` only all the time, and use/update the functions of `TestModule` easily. Also, all the functions there can be provided as example/test functions for users, such as:

```julia-auto
using MyPackage: foo
using MyPackageTests # loads all dependencies of TestModule

data = MyPackage.TestModule.generate_data()
MyPackage.foo(data)

```

Is there any obvious downside of this? Having to register a dummy package seems overkill here, but not a major problem.

The `TestModule` package will never be loaded from within the functions of `MyPackage`, such that the implications for loading time of `MyPackage` are minimal (if any?). Or is this wrong?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [March 17, 2023, 5:39pm UTC](https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247/2 "2023-03-17T17:39:18Z")

</div>

> [@lmiq](#):
>
> #### 2. Create a dummy `MyPackageTests` package, basically empty, and register it.

Yeah, no, there will not be a bunch of empty packages getting registered. The current situation might be non-ideal for the use-case here (I must admit I did not fully understand it), but anything that requires registering “basically empty” packages is just unworkable and unscalable.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [March 18, 2023, 12:15pm UTC](https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247/4 "2023-03-18T12:15:08Z")

</div>

After reading again the new extensions docs and understanding it better, I think that this is fine, then:

```julia
name = "MyPackage"
version = "0.1.0"
uuid = "..."

[weakdeps]
Plots = "d38c429a-6771-53c6-b99e-75d170b6e991"

[extensions]
MyTestModule = "Plots" # only loaded if MyPackageTests is loaded

[compat]
Plots = "0.6.2"

```

and define `MyTestModule` in `ext/MyTestModule.jl`.

`Plots` will only be loaded if `MyTestModule` is loaded explicitly, which does what I want there. This is useful when functions defined for testing are also useful outside the scope of testing (as for generating data for examples, or even for debugging), as the function are available to be used in general without carrying the dependencies that are not really necessary for the main functionality of the package.

With the `TestItems` package, which I find very useful, now one can do:

```julia
@testitem "foo" begin
    using MyPackage: foo
    using MyPackage.MyTestModule: generate_data_for_foo
    @test foo(generate_data_for_foo()) == result
end

```

with `MyTestModule` carrying everything needed to test, which might not be part of the package itself.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [March 18, 2023, 1:58pm UTC](https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247/5 "2023-03-18T13:58:35Z")

</div>

> [@lmiq](#):
>
> `Plots` will only be loaded if `MyTestModule` is loaded explicitly,

Rather the opposite, `MyTestModule` will be automatically loaded if `Plots` is also loaded.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [March 18, 2023, 2:35pm UTC](https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247/6 "2023-03-18T14:35:11Z")

</div>

Oh, I see… Got confused about that indeed. Then well, my first interpretation was correct, and for this purpose it is less practical, without the dummy package.

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [April 7, 2025, 7:26pm UTC](https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247/7 "2025-04-07T19:26:26Z")

</div>

I recently thought about that. What if you make the `TestModule` depend on `Test`? I think that would be sweet. The problem I see is that weak dependencies are not meant to export new functions. But I think there is a way around it if you get reference to the module with `Base.get_extension`.

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [April 7, 2025, 9:11pm UTC](https://discourse.julialang.org/t/using-weakdeps-and-extensions-to-carry-on-a-test-module/96247/9 "2025-04-07T21:11:58Z")

</div>

It works as expected 🙂
