# Organizing Julia code

**URL:** <https://discourse.julialang.org/t/organizing-julia-code/42081>\
**Category:** New to Julia\
**Tags:** question, code-organization\
**Created:** [June 25, 2020, 11:53pm UTC](https://discourse.julialang.org/t/organizing-julia-code/42081 "2020-06-25T23:53:34Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![alan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alan/32/15970_2.png) [@alan](https://discourse.julialang.org/u/alan)\
**Post date:** [June 25, 2020, 11:53pm UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/1 "2020-06-25T23:53:34Z")

</div>

I understand that Julia projects conventionally have src and test directories. How does one connect the latter to the former? This works:

```
  include("../src/foo.jl")

```

But perhaps there is a better way, involving some configuration file within the project?

Is there a convention for naming unit tests and integration tests? Can someone recommend a small package that I could use as a model?

Thanks

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [June 26, 2020, 12:55am UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/2 "2020-06-26T00:55:01Z")

</div>

Do you want a package or just a project? Check out [4. Working with Environments · Pkg.jl](https://julialang.github.io/Pkg.jl/v1/environments/#Creating-your-own-projects-1) and if you’re after a package, then PkgTemplates.jl ([GitHub - invenia/PkgTemplates.jl: Create new Julia packages, the easy way](https://github.com/invenia/PkgTemplates.jl)) are the way to go.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 26, 2020, 9:55am UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/3 "2020-06-26T09:55:04Z")

</div>

Usually one would be

```julia
using ThatModule

```

in the unit tests.

A tiny package that I like is

> **[GitHub - mauro3/UnPack.jl: \`@pack!\` and \`@unpack\` macros](https://github.com/mauro3/UnPack.jl)**
>
> \`@pack!\` and \`@unpack\` macros. Contribute to mauro3/UnPack.jl development by creating an account on GitHub.

and may be useful as an example.

You may want to use a package template generator too, eg

> **[GitHub - JuliaCI/PkgTemplates.jl: Create new Julia packages, the easy way](https://github.com/JuliaCI/PkgTemplates.jl)**
>
> Create new Julia packages, the easy way. Contribute to JuliaCI/PkgTemplates.jl development by creating an account on GitHub.

> **[GitHub - tpapp/PkgSkeleton.jl: Generate Julia package skeletons using a...](https://github.com/tpapp/PkgSkeleton.jl)**
>
> Generate Julia package skeletons using a simple template system - GitHub - tpapp/PkgSkeleton.jl: Generate Julia package skeletons using a simple template system

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [June 26, 2020, 9:59am UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/4 "2020-06-26T09:59:39Z")

</div>

As a starting point,  
I typically mirror the folder structure of `src` in test.  
So if i have files: `src/foo.jl` and `src/bar.jl` I will also have `test/foo.jl` and `test/bar.jl`.

then i might also add seperate files on top for integration testing,  
or i might not.  
Depending on the project

---

<div class="post-metadata">

**Author:** ![alan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alan/32/15970_2.png) [@alan](https://discourse.julialang.org/u/alan)\
**Post date:** [June 26, 2020, 7:53pm UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/5 "2020-06-26T19:53:57Z")

</div>

I’ve had a look at UnPack.jl and am still confused. Under UnPack.jl, the test directory has a file called runtests.jl, which begins with

```
using UnPack

```

When I execute that file (`julia runtests.jl`), I get

```
[Alans-MacBook-Air test]$ julia runtests.jl
ERROR: LoadError: ArgumentError: Package UnPack not found in current path:
- Run `import Pkg; Pkg.add("UnPack")` to install the UnPack package.

Stacktrace:
 [1] require(::Module, ::Symbol) at ./loading.jl:892
 [2] include(::Module, ::String) at ./Base.jl:377
 [3] exec_options(::Base.JLOptions) at ./client.jl:288
 [4] _start() at ./client.jl:484
 in expression starting at /Users/rogers/distrib/UnPack/test/runtests.jl:2

```

Clearly, the Project.toml file is not enough to tell Julia how to find the source code. Do I need to install or activate this package using the package manager? If I do that, how can I be sure I’m testing the local code (in …/src) rather than a version installed elsewhere by Pkg?

Thanks

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [June 26, 2020, 8:02pm UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/6 "2020-06-26T20:02:19Z")

</div>

Workflow is like this:

1. Run `]activate .; instantiate` in the package folder.
2. Afterwards run `]test`.

---

<div class="post-metadata">

**Author:** ![alan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alan/32/15970_2.png) [@alan](https://discourse.julialang.org/u/alan)\
**Post date:** [June 26, 2020, 8:41pm UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/7 "2020-06-26T20:41:31Z")

</div>

This works from within the REPL, but from the Unix shell,

```
julia runtest.jl

```

still bombs. Is this as expected?

Thanks for the help.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [June 26, 2020, 9:12pm UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/8 "2020-06-26T21:12:11Z")

</div>

Yes. You can make a script to run the tests from what I posted.

```julia
using Pkg
Pkg.activate(".");
Pkg.instantiate()
Pkg.test()

```

Call it “mytest.jl” and run as `julia mytest.jl`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 27, 2020, 6:51am UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/9 "2020-06-27T06:51:38Z")

</div>

> [@alan](#):
>
> Is this as expected?

Yes.

Also, most people use an interactive REPL for Julia, usually from some editor/IDE. If you want to run things from the command line, you will face the cost of compilation each time, so it will be frustrating way of using Julia.

---

<div class="post-metadata">

**Author:** ![Kirby\_Zhang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kirby_zhang/32/36204_2.png) [@Kirby\_Zhang](https://discourse.julialang.org/u/Kirby_Zhang)\
**Post date:** [June 21, 2022, 5:52am UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/10 "2022-06-21T05:52:56Z")

</div>

The manual section [Code Loading · The Julia Language](https://docs.julialang.org/en/v1/manual/code-loading/#code-loading) describes how name conflicts can occur when you use a private name that ends up being in the public space created by other popular packages.  
I would suggest a useful convention is calling private modules MyData, MyTest etc, these modules would not have name conflicts and you wouldn’t have to carefully manage the coding loading environment.

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [June 21, 2022, 8:45am UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/11 "2022-06-21T08:45:49Z")

</div>

> [@alan](#):
>
> from the Unix shell

One way is to use `julia --project` from your project’s root directory.

First I make a dummy project:

```fish
max@opt ~/sandbox> julia
               _
   _ _ _(_)_ | Documentation: https://docs.julialang.org
  (_) | (_) (_) |
   _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` | |
  | | |_| | | | (_| | | Version 1.8.0-beta1 (2022-02-23)
 _/ |\ __'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |

(@v1.8) pkg> generate MyNewJuliaProject
  Generating project MyNewJuliaProject:
    MyNewJuliaProject/Project.toml
    MyNewJuliaProject/src/MyNewJuliaProject.jl

julia> exit()

```

Next I cd into the project and create some tests. Then do `julia --project`, add the `Test` package itself as a dependency (you only have to do this once), then run `]test` which should automatically do all the tests in your `runtests.jl`:

```fish
max@opt ~/sandbox> cd MyNewJuliaProject/
max@opt ~/s/MyNewJuliaProject> mkdir test
max@opt ~/s/MyNewJuliaProject> echo "using Test; @test true" > test/runtests.jl
max@opt ~/s/MyNewJuliaProject> julia --project
               _
   _ _ _(_)_ | Documentation: https://docs.julialang.org
  (_) | (_) (_) |
   _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` | |
  | | |_| | | | (_| | | Version 1.8.0-beta1 (2022-02-23)
 _/ |\ __'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |

(MyNewJuliaProject) pkg> add Test
    Updating registry at `~/.julia/registries/General.toml`
   Resolving package versions...
    Updating `~/sandbox/MyNewJuliaProject/Project.toml`
  [8dfed614] + Test
    Updating `~/sandbox/MyNewJuliaProject/Manifest.toml`
  [2a0f44e3] + Base64
  [b77e0a4c] + InteractiveUtils
  [56ddb016] + Logging
  [d6f4376e] + Markdown
  [9a3f8284] + Random
  [ea8e919c] + SHA v0.7.0
  [9e88b42a] + Serialization
  [8dfed614] + Test

(MyNewJuliaProject) pkg> test
     Testing MyNewJuliaProject
      Status `/tmp/jl_6ouu8z/Project.toml`
  [a2f463a9] MyNewJuliaProject v0.1.0 `~/sandbox/MyNewJuliaProject`
  [8dfed614] Test `@stdlib/Test`
      Status `/tmp/jl_6ouu8z/Manifest.toml`
  [a2f463a9] MyNewJuliaProject v0.1.0 `~/sandbox/MyNewJuliaProject`
  [2a0f44e3] Base64 `@stdlib/Base64`
  [b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
  [56ddb016] Logging `@stdlib/Logging`
  [d6f4376e] Markdown `@stdlib/Markdown`
  [9a3f8284] Random `@stdlib/Random`
  [ea8e919c] SHA v0.7.0 `@stdlib/SHA`
  [9e88b42a] Serialization `@stdlib/Serialization`
  [8dfed614] Test `@stdlib/Test`
     Testing Running tests...
     Testing MyNewJuliaProject tests passed

(MyNewJuliaProject) pkg>

julia> exit()

```

Another way is to `]develop` your package on your “main” Julia environment. This lets you use plain-old `julia` (without the `--project` flag) and you can use packages you have on your Julia environment without adding them as dependencies.

```fish
max@opt ~/s/MyNewJuliaProject> cd ~
max@opt ~> julia
               _
   _ _ _(_)_ | Documentation: https://docs.julialang.org
  (_) | (_) (_) |
   _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` | |
  | | |_| | | | (_| | | Version 1.8.0-beta1 (2022-02-23)
 _/ |\ __'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |

(@v1.8) pkg> develop /home/max/sandbox/MyNewJuliaProject/
   Resolving package versions...
    Updating `~/.julia/environments/v1.8/Project.toml`
  [a2f463a9] + MyNewJuliaProject v0.1.0 `~/sandbox/MyNewJuliaProject`
    Updating `~/.julia/environments/v1.8/Manifest.toml`
  [a2f463a9] + MyNewJuliaProject v0.1.0 `~/sandbox/MyNewJuliaProject`

(@v1.8) pkg> test MyNewJuliaProject
     Testing MyNewJuliaProject
      Status `/tmp/jl_C8tprf/Project.toml`
  [a2f463a9] MyNewJuliaProject v0.1.0 `~/sandbox/MyNewJuliaProject`
  [8dfed614] Test `@stdlib/Test`
      Status `/tmp/jl_C8tprf/Manifest.toml`
  [a2f463a9] MyNewJuliaProject v0.1.0 `~/sandbox/MyNewJuliaProject`
  [2a0f44e3] Base64 `@stdlib/Base64`
  [b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
  [56ddb016] Logging `@stdlib/Logging`
  [d6f4376e] Markdown `@stdlib/Markdown`
  [9a3f8284] Random `@stdlib/Random`
  [ea8e919c] SHA v0.7.0 `@stdlib/SHA`
  [9e88b42a] Serialization `@stdlib/Serialization`
  [8dfed614] Test `@stdlib/Test`
     Testing Running tests...
     Testing MyNewJuliaProject tests passed

(@v1.8) pkg>

```

Edit: Just realized how old this thread was. Hope this was helpful to someone anyhow.

---

<div class="post-metadata">

**Author:** ![Kirby\_Zhang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kirby_zhang/32/36204_2.png) [@Kirby\_Zhang](https://discourse.julialang.org/u/Kirby_Zhang)\
**Post date:** [June 21, 2022, 1:30pm UTC](https://discourse.julialang.org/t/organizing-julia-code/42081/12 "2022-06-21T13:30:33Z")

</div>

I still cannot figure out how to use both versioned public packages, and my own unversioned modules in the same project. When I add a Project.toml file to my directory, I can no longer load my own modules, unless I create a package with UUID for every single module.  
I looked at packaged like PyCall, PythonCall, DataFrames, they all have just one massive module and include a bunch of source files. They don’t even use the module feature to separate program logic, within their own project.
