Skip to content
AgileLogics
6 min read

Testing

Prerequisites: Packages and environments

The Test standard library provides everything you need for unit tests.

using Test

slugify(s) = lowercase(replace(strip(s), r"[^A-Za-z0-9]+" => "-"))

println(@test slugify("Hello World") == "hello-world")
println(@test slugify("  Julia 1.13!  ") == "julia-1-13-")
println(@test_throws MethodError slugify(42))
println(@test 0.1 + 0.2 ≈ 0.3)
Test Passed
Test Passed
Test Passed
      Thrown: MethodError
Test Passed
  • @test expr passes if expr is true.
  • @test_throws ExceptionType expr passes if expr throws that type.
  • ≈ (or isapprox with atol/rtol) for floating-point results.

Failures show the values

# illustrative — the stack trace and Time column are shortened/vary
using Test

add(a, b) = a + b + 1        # a bug
try
    @testset "arithmetic" begin
        @test add(2, 2) == 4
    end
catch
end
arithmetic: Test Failed at main.jl:6
  Expression: add(2, 2) == 4
   Evaluated: 5 == 4
  Stacktrace:
  ...
Test Summary: | Fail  Total  Time
arithmetic    |    1      1  1.9s
RNG of the outermost testset: Random.Xoshiro(...)

When a test fails, Julia shows the expression and the evaluated values (5 == 4), which usually points right at the bug. A failing top-level @testset throws at the end — that's what makes CI fail.

Test sets

# illustrative — the Time column varies
using Test

slugify(s) = lowercase(replace(strip(s), r"[^A-Za-z0-9]+" => "-"))

@testset "slugify" begin
    @test slugify("A B") == "a-b"
    @testset "edge cases" begin
        @test slugify("") == ""
        @test slugify("---") == "-"
    end
end
Test Summary: | Pass  Total  Time
slugify       |    3      3  0.1s

@testset groups tests, keeps going after a failure, and prints a summary. Nest them to organize large suites.

Package tests

A package keeps its tests in test/runtests.jl:

# illustrative — test/runtests.jl
using MyPackage
using Test

@testset "MyPackage" begin
    include("parsing_tests.jl")
    include("model_tests.jl")
end

Run them with ] test (or Pkg.test()) — Pkg creates a temporary environment with the test dependencies, so tests run against exactly what's declared. julia --project -e 'using Pkg; Pkg.test()' is the usual CI command.

More tools

  • Documenter.jl runs the examples in your docstrings as doctests.
  • Aqua.jl checks packages for ambiguities, type piracy, and missing compat entries.
  • JET.jl finds type errors and instabilities statically.
  • ReTest.jl and TestItemRunner.jl run subsets of tests quickly (the VS Code extension understands @testitem).
  • --code-coverage plus Coverage.jl measures coverage.