如何在 Julia 中创建动态命名的测试集?

Ale*_*lec 3 testing julia

使用 Julia 的 Test 包,如何创建@testset在运行时引用值的 s?

例如我有

test_data = [
   (model="a",datapath="models/a.json"),
   (model="b",datapath="models/b.json"),
   ...
] 
Run Code Online (Sandbox Code Playgroud)

我想这样做:

@testset "models" begin
    for test in test_data
        @testset test.model begin
            
            # test range of values/functions here
        end
    end

end
Run Code Online (Sandbox Code Playgroud)

但是我收到这样的错误,我认为这是因为我试图在运行时定义测试集名称。

ERROR: LoadError: LoadError: LoadError: Unexpected argument test.model to @testset
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] parse_testset_args(::Tuple{Expr}) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\Test\src\Test.jl:1244
 [3] testset_beginend(::Tuple{Expr,Expr}, ::Expr, ::LineNumberNode) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\Test\src\Test.jl:1087
 [4] @testset(::LineNumberNode, ::Module, ::Vararg{Any,N} where N) at D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\Test\src\Test.jl:1079
 [5] include(::String) at .\client.jl:457
 [6] top-level scope at C:\MyPackage\runtests.jl:7
 [7] include(::String) at .\client.jl:457
 [8] top-level scope at none:6
Run Code Online (Sandbox Code Playgroud)

因为我在每个内部运行数百个测试,@testset所以在运行测试时将结果分组会非常好。此外,当我收到错误时,它往往会出现在许多结果中,并且我的终端会丢失上面错误开始处的历史记录,因此在每组测试之前打印模型名称也不能很好地工作。

ffe*_*tte 5

您可以使用标准语法在测试名称中插入表达式的值$


julia> using Test

julia> i = 1
1

julia> @testset "Model $i" begin
           @test true
       end
Test Summary: | Pass  Total
Model 1       |    1      1
Run Code Online (Sandbox Code Playgroud)

但是在您的情况下,使用@testset for ... end语法而不是更常见的语法可能更好@testset begin ... end(有关更详细的解释,请参阅文档):

julia> @testset "Model $i" for i in 1:2
           @test i == i
       end
Test Summary: | Pass  Total
Model 1       |    1      1
Test Summary: | Pass  Total
Model 2       |    1      1
Run Code Online (Sandbox Code Playgroud)

在您的特定用例中,它看起来像:

julia> test_data = [
          (model="a",datapath="models/a.json"),
          (model="b",datapath="models/b.json"),
       ]
2-element Array{NamedTuple{(:model, :datapath),Tuple{String,String}},1}:
 (model = "a", datapath = "models/a.json")
 (model = "b", datapath = "models/b.json")

julia> @testset "Model $(test.model)" for test in test_data
           @test test.datapath == "models/$(test.model).json"
       end
Test Summary: | Pass  Total
Model a       |    1      1
Test Summary: | Pass  Total
Model b       |    1      1
Run Code Online (Sandbox Code Playgroud)