I have a query about how to structure the contents of a unit test file.
In many cases, ideally, for each test we will have an independent scope. This is to prevent information leakage between different test cases.
The documentation suggests that the @testset
macro is used to define a scope.
However, it also suggests the purpose of this macro serves a different purpose - to group tests into logical groups.
The
@testset
macro can be used to group tests into sets . All the tests in a test set will be run, and at the end of the test set a summary will be printed. If any of the tests failed, or could not be evaluated due to an error, the test set will then throw aTestSetException
.
Here’s an example of how a typical runTests.jl
file might be structured.
# runTests.jl
include("testComponentA.jl")
include("testComponentB.jl")
To run it, I use a short script, which lives in the same directory.
#!/usr/bin/bash
julia --project -e 'using Pkg; Pkg.test()'
Here’s how each of the individual test files might be structured. I didn’t make these files into modules by including module ... end
. Possibly I should have.
Each component of the source code, for example a module which performs some self-contained function, has a corresponding file in the test directory containing its tests.
# testComponentA.jl
# this is not a module, maybe it should be
include("../src/ComponentA.jl")
using Main.ComponentAModule
using Test
@testset "ComponentAModuleTests" begin
# this is a single unit test
component = ComponentA()
@test component.someFunction() == someValue
# this is an independent unit test from the above
# should it be part of the same test set?
component2 = ComponentA()
@test component2.someOtherFunction() == someOtherValue
# information leakage: component != component2
# easy to use `component` instead of `component2`
# and thus make a mistake in test code
end
My question here being, is this the right use of @testset
or should @testset
be used to create and destroy scope for individual unit tests. (To prevent information leakage.)
Related to the above, is it possible to create a new scope using a let
statement? Something like
let
# put a single test here
end
I’m not sure if that is valid syntax, because the let
is not associated with any value. When I tried it, it seemed to be valid however.
Perhaps a combination of both should be used?