让Julia测试套件在运行结束时报告所有错误消息

时间:2019-01-30 10:17:12

标签: unit-testing error-handling julia test-suite

我正在使用Julia测试套件功能,我非常喜欢它。 但是,我无法弄清楚的是如何让测试者在完成后报告潜在的消息。

假设我有一个类似于下面的测试套件,其中每个函数在返回之前依次执行一堆测试

@testset "MyTestSuite" begin
    @testset "Subtest1" begin @test my_test_1() end
    @testset "Subtest2" begin @test my_test_2() end
    @testset "Subtest3" begin @test my_test_3() end
    @testset "Subtest4" begin @test my_test_4() end
end

如果现在说my_test_4失败或引发错误,则输出中看起来像以下

Test Summary:                                   |    Pass  Error    Total
MyTestSuite                                     |      65      1       66
  Subtest1                                      |       5      1        6
  Subtest2                                      |      10      0       10
  Subtest3                                      |      20      0       20
  Subtest4                                      |      30      0       30
ERROR: LoadError: Some tests did not pass: 65 passed, 0 failed, 1 errored, 0 broken.

但是(据我所知)现在有一种方法可以让我看到问题所在而无需在终端输出中向上滚动。如果我的测试套件足够长,并且能够产生足够的诊断信息,则错误信息甚至可能丢失给我,或者至少很难找到。

那么,有人知道解决这个问题的好方法吗?是否有选项,一个可以给宏@testset,以确保它打印收集的误差进行进一步的处理?

1 个答案:

答案 0 :(得分:1)

您可以定义自定义AbstractTestSet。它在Julia手册中here中有描述。

这是从手册改编而成的示例。首先定义:

using Test

struct CustomTestSet <: Test.AbstractTestSet
    description::AbstractString
    results::Vector
    CustomTestSet(desc) = new(desc, [])
end

Test.record(ts::CustomTestSet, child::Test.AbstractTestSet) = push!(ts.results, child)
Test.record(ts::CustomTestSet, res::Test.Result) = push!(ts.results, res)

function Test.finish(ts::CustomTestSet)
    if Test.get_testset_depth() > 0
        Test.record(Test.get_testset(), ts)
    end
    ts
end

现在您可以写:

julia> res = @testset CustomTestSet "custom testset" begin
           # this testset should inherit the type, but not the argument.
           @testset "custom testset inner" begin
               @test 1==1
               @test 1==2
               @test 2==2
               @test 2==3
           end
       end
CustomTestSet("custom testset", Any[CustomTestSet("custom testset inner", Any[Test Passed, Test Failed at REPL[10]:5
  Expression: 1 == 2
   Evaluated: 1 == 2, Test Passed, Test Failed at REPL[10]:7
  Expression: 2 == 3
   Evaluated: 2 == 3])])

julia> res.results[1].results
4-element Array{Any,1}:
 Test Passed
 Test Failed at REPL[10]:5
  Expression: 1 == 2
   Evaluated: 1 == 2
 Test Passed
 Test Failed at REPL[10]:7
  Expression: 2 == 3
   Evaluated: 2 == 3

您可以访问一个向量,该向量会告诉您哪些内容通过了哪些内容以及哪些内容失败了,而在失败时是什么问题了。

您还可以过滤出通过的测试:

julia> filter(x -> !(x isa Test.Pass), res.results[1].results)
2-element Array{Any,1}:
 Test Failed at REPL[6]:5
  Expression: 1 == 2
   Evaluated: 1 == 2
 Test Failed at REPL[6]:7
  Expression: 2 == 3
   Evaluated: 2 == 3

如果您的测试具有更复杂的嵌套结构,则应递归执行。

这是您想要的吗?