Strange text output from running Julia tests

I’m getting this somewhat mysterious output when running some of my Julia tests. I don’t recall seeing this yesterday.

Test.DefaultTestSet("someModule", Any[], 8, false, false, true, 1.730981062858112e9, 1.730981062860939e9, false, "/home/user/path/test/someModule.jl")

Sorry for the “dumb” question - but what is this? What causes this text to be printed? Where does it come from?

That’s the display of a testset:

julia> @testset begin
           @test true
       end;
Test Summary: | Pass  Total  Time
test set      |    1      1  0.0s

julia> @testset begin
           @test true
       end
Test Summary: | Pass  Total  Time
test set      |    1      1  0.0s
Test.DefaultTestSet("test set", Any[], 1, false, false, true, 1.730981704137089e9, 1.73098170413711e9, false, "REPL[4]")

Note that in the first case I put a semicolon to suppress the display in the REPL. That said, hard to tell why are you seeing that without knowing what you’re doing exactly in the first place.

1 Like

Here’s a further strange observation.

Adding the semicolon has no effect.

However, adding the semicolon, followed by

println("DONE")

does prevent Test.DefaultTestSet(...) from being printed. However, of course, it will now print DONE instead.

It really depends on how you’re running the tests. The key thing to note is that — just like you’ve seen in other threads — Julia is an expression-based language and every expression has a return value. That value might be the thing called nothing (which doesn’t display itself at all), or it might be something like a TestSet, which prints as it’s running and then can display a representation of the object.

The semicolon is just a “flag” to tell the REPL not to display the object that’s returned. So the place to put it is literally on the REPL input line. If you’re running the tests with an include, that’s:

julia> include("test/runtests.jl");
Test Summary: | Pass  Total  Time
test set      |    1      1  0.0s

julia>  # ^^ Look, no extra output
3 Likes

I usually put the value nothing on the last line of my runtests.jl to avoid exactly this output

3 Likes

Thanks, I’ll just do the same thing.

If you have nested @testsets, do you need to put return nothing at the end of each, or just at the end of the outer test set?

I know I can easily test this but since I haven’t been seeing the same behavior as expected (because I don’t know exactly what to expect) I’m hoping you can tell me which of the two cases it is.

Generally, you’ll only need it after the outer testset. Or, if things are split over multiple files, potentially at the end of every file.

The point is that the REPL prints the result of any top-level expression it evaluates. If that expression is an include, and you don’t want the result of the last expression in the included file to be printed, you can make that last expression in the file be nothing.

This really goes back to your earlier confusion

which is just completely false in Julia. All expressions in Julia (including include) return something. Moreover, the convention is for things to return the last expression from their “body”. There does not need to be an explicit return statement, and things return nothing only if they explicitly return nothing (or the last expression they contain returns nothing).

In this case putting nothing at the end of the file make that the last expression in the “body” of the include, and thus causes include to return nothing, and nothing to be printed in the REPL.

3 Likes

I don’t particularly appreciate this comment.

I am not, as you put it “confused”. I objected to this particular Julia function behaving in an unusual way, a way which is different to all other functions in any other programming language which I know of.

As it happens, I was persuaded by the discussion. Now my opinion is somewhat different.

I should have said “question”, not “confusion”. This was not meant as an insult. Julia has many design decisions that lead to things working differently from other languages, in subtle ways. For someone relatively new to the language, it is more than natural to have their assumptions challenged. It takes months (at least) to understand the nuances of some of Julia’s concepts. For example, it took me some time to really understand why if I define a function f(a) I can’t call with f(a=1), the way I can in Python and Fortran. That is, the full consequences of multiple dispatch as a central paradigm of the language. And, some (smaller) design decisions might be arbitrary, and might even be something that I disagree with (if substr in str comes to mind).

In this case, it seemed that there was a design decision in Julia about expressions and their return values that you hadn’t fully wrapped your head around yet. Again, nothing wrong with that! I just wanted to point out the connection between the two questions, as they both derived from not fully being familiar yet with the same principle of Julia’s design.

4 Likes

I usually put

nothing

as last line of a test script to avoid strange output.