Skip to content

Commit 113b887

Browse files
committed
Capture and print test output separately.
1 parent ca7994f commit 113b887

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

src/ParallelTestRunner.jl

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ abstract type AbstractTestRecord end
6767

6868
struct TestRecord <: AbstractTestRecord
6969
test::Any
70+
output::String
7071
time::Float64
7172
bytes::UInt64
7273
gctime::Float64
@@ -154,6 +155,10 @@ function print_test_finished(test, wrkr, record::TestRecord, ctx::TestIOContext)
154155
rss_str = @sprintf("%5.2f", record.rss / 2^20)
155156
printstyled(ctx.stdout, lpad(rss_str, ctx.rss_align, " "), " |\n", color = :white)
156157

158+
for line in eachline(IOBuffer(record.output))
159+
println(ctx.stdout, " "^(ctx.name_align + 2), "| ", line)
160+
end
161+
157162
flush(ctx.stdout)
158163
finally
159164
unlock(ctx.lock)
@@ -186,34 +191,39 @@ function runtest(::Type{TestRecord}, f, name, init_code)
186191
# generate a temporary module to execute the tests in
187192
mod_name = Symbol("Test", rand(1:100), "Main_", replace(name, '/' => '_'))
188193
mod = @eval(Main, module $mod_name end)
189-
@eval(mod, import ParallelTestRunner: Test, Random)
194+
@eval(mod, import ParallelTestRunner: Test, Random, IOCapture)
190195
@eval(mod, using .Test, .Random)
191196

192197
Core.eval(mod, init_code)
198+
193199
data = @eval mod begin
194200
GC.gc(true)
195201
Random.seed!(1)
196202

197-
res = @timed @testset $name begin
198-
$f
203+
res = @timed IOCapture.capture() do
204+
@testset $name begin
205+
$f
206+
end
199207
end
200-
(; res.value, res.time, res.bytes, res.gctime)
208+
captured = res.value
209+
(; testset=captured.value, captured.output, res.time, res.bytes, res.gctime)
201210
end
202211

203212
# process results
204213
rss = Sys.maxrss()
205214
if VERSION >= v"1.11.0-DEV.1529"
206-
tc = Test.get_test_counts(data.value)
215+
tc = Test.get_test_counts(data.testset)
207216
passes, fails, error, broken, c_passes, c_fails, c_errors, c_broken =
208217
tc.passes, tc.fails, tc.errors, tc.broken, tc.cumulative_passes,
209218
tc.cumulative_fails, tc.cumulative_errors, tc.cumulative_broken
210219
else
211220
passes, fails, errors, broken, c_passes, c_fails, c_errors, c_broken =
212-
Test.get_test_counts(data.value)
221+
Test.get_test_counts(data.testset)
213222
end
214-
if data[1].anynonpass == false
215-
data = (
216-
(passes + c_passes, broken + c_broken),
223+
if !data.testset.anynonpass
224+
data = (;
225+
result=(passes + c_passes, broken + c_broken),
226+
data.output,
217227
data.time,
218228
data.bytes,
219229
data.gctime,
@@ -536,19 +546,18 @@ function runtests(ARGS; testfilter = Returns(true), RecordType = TestRecord,
536546
print_header(RecordType, io_ctx, testgroupheader, workerheader)
537547

538548
status_lines_visible = Ref(0)
549+
539550
function clear_status()
540551
if status_lines_visible[] > 0
541-
for i in 1:status_lines_visible[]
542-
width = displaysize(io_ctx.stdout)[2]
543-
print(io_ctx.stdout, "\r", " "^width, "\r")
544-
if i < status_lines_visible[]
545-
print(io_ctx.stdout, "\033[1A") # Move up
546-
end
552+
for i in 1:status_lines_visible[]-1
553+
print(io_ctx.stdout, "\033[1A") # Move up one line
554+
print(io_ctx.stdout, "\033[2K") # Clear entire line
547555
end
548-
print(io_ctx.stdout, "\r")
556+
print(io_ctx.stdout, "\r") # Move to start of line
549557
status_lines_visible[] = 0
550558
end
551559
end
560+
552561
function update_status()
553562
# only draw the status bar on actual terminals
554563
io_ctx.stdout isa Base.TTY || return
@@ -636,7 +645,7 @@ function runtests(ARGS; testfilter = Returns(true), RecordType = TestRecord,
636645
end
637646

638647
# After a while, display a status line
639-
if time() - t0 >= 5 && (got_message || (time() - last_status_update[] >= 1))
648+
if !done && time() - t0 >= 5 && (got_message || (time() - last_status_update[] >= 1))
640649
update_status()
641650
last_status_update[] = time()
642651
end
@@ -847,7 +856,7 @@ function runtests(ARGS; testfilter = Returns(true), RecordType = TestRecord,
847856
c = IOCapture.capture() do
848857
Test.record(fake, Test.Error(:test_interrupted, test, nothing, Base.ExceptionStack([(exception = "skipped", backtrace = [])]), LineNumberNode(1)))
849858
end
850-
print(io_ctx.stdout, c.output)
859+
# don't print the output of interrupted tests, it's not useful
851860
with_testset(fake) do
852861
Test.record(o_ts, fake)
853862
end

test/runtests.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,20 @@ end
112112
@test contains(str, "This test throws an error")
113113
end
114114

115+
@testset "test output" begin
116+
custom_tests = Dict(
117+
"output" => quote
118+
println("This is some output from the test")
119+
end
120+
)
121+
122+
io = IOBuffer()
123+
runtests(["--verbose"]; custom_tests, stdout=io, stderr=io)
124+
125+
str = String(take!(io))
126+
@test contains(str, r"output .+ started at")
127+
@test contains(str, r"This is some output from the test")
128+
@test contains(str, "SUCCESS")
129+
end
130+
115131
end

0 commit comments

Comments
 (0)