Unit testing 让Julia testsuite在运行结束时报告所有错误消息

Unit testing 让Julia testsuite在运行结束时报告所有错误消息,unit-testing,error-handling,julia,test-suite,Unit Testing,Error Handling,Julia,Test Suite,我正在玩Julia testsuite的功能,我非常喜欢它。 然而,我没有弄清楚的是,如何让testsuite在完成时报告潜在的消息 假设我有一个测试套件,如下所示,其中每个函数在返回之前依次执行一系列测试 @testset "MyTestSuite" begin @testset "Subtest1" begin @test my_test_1() end @testset "Subtest2" begin @test my_test_2() end @testset

我正在玩Julia testsuite的功能,我非常喜欢它。 然而,我没有弄清楚的是,如何让testsuite在完成时报告潜在的消息

假设我有一个测试套件,如下所示,其中每个函数在返回之前依次执行一系列测试

@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\u 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
提供选项,以确保它打印并收集错误以供进一步处理?

您可以定义自定义
抽象测试集。这在朱莉娅手册中有描述

以下是根据手册改编的示例。首先定义:

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> 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
如果您的测试有一个更复杂的嵌套结构,您应该递归地执行它


这是你想要的吗?

这当然符合我的要求,而且已经非常有用了。但是,您编写的函数还记录了所有成功的测试。在我的例子中,这有点问题,因为我自动生成了很多测试(通过plang@test-wihing-foor循环),这些测试也会显示出来。您的解决方案是否有一个很好的调整,以便只记录失败的测试?是的,只是过滤掉成功的测试。我将在答案中给出一个例子。
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