Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document and export TestLogger and LogRecord #44080

Merged
merged 1 commit into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ Standard library changes
function is provided to reproduce the mapping used in identifier normalization
by the Julia parser ([#42561]).

#### Test
* `TestLogger` and `LogRecord` are now exported from the Test stdlib. ([#44080])


Deprecated or removed
---------------------
Expand Down
11 changes: 10 additions & 1 deletion stdlib/Test/docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ Foo Tests | 3 1 4 0.0s
ERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken.
```

## Testing Log Statements

One can use the [`@test_logs`](@ref) macro to test log statements, or use a [`TestLogger`](@ref).

```@docs
Test.@test_logs
Test.TestLogger
Test.LogRecord
```

## Other Test Macros

As calculations on floating-point values can be imprecise, you can perform approximate equality
Expand All @@ -226,7 +236,6 @@ Note that this is not a specific feature of the `≈` but rather a general featu

```@docs
Test.@inferred
Test.@test_logs
Test.@test_deprecated
Test.@test_warn
Test.@test_nowarn
Expand Down
1 change: 1 addition & 0 deletions stdlib/Test/src/Test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export @inferred
export detect_ambiguities, detect_unbound_args
export GenericString, GenericSet, GenericDict, GenericArray, GenericOrder
export TestSetException
export TestLogger, LogRecord

using Random
using Random: AbstractRNG, default_rng
Expand Down
51 changes: 50 additions & 1 deletion stdlib/Test/src/logging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,20 @@ using Logging: Logging, AbstractLogger, LogLevel, Info, with_logger
import Base: occursin

#-------------------------------------------------------------------------------
# Log records
"""
LogRecord

Stores the results of a single log event. Fields:

* `level`: the [`LogLevel`](@ref) of the log message
* `message`: the textual content of the log message
* `_module`: the module of the log event
* `group`: the logging group (by default, the name of the file containing the log event)
* `id`: the ID of the log event
* `file`: the file containing the log event
* `line`: the line within the file of the log event
* `kwargs`: any keyword arguments passed to the log event
"""
struct LogRecord
level
message
Expand All @@ -30,6 +43,42 @@ mutable struct TestLogger <: AbstractLogger
respect_maxlog::Bool
end

"""
TestLogger(; min_level=Info, catch_exceptions=false)

Create a `TestLogger` which captures logged messages in its `logs::Vector{LogRecord}` field.

Set `min_level` to control the `LogLevel`, `catch_exceptions` for whether or not exceptions
thrown as part of log event generation should be caught, and `respect_maxlog` for whether
or not to follow the convention of logging messages with `maxlog=n` for some integer `n` at
most `n` times.

See also: [`LogRecord`](@ref).

## Example

```jldoctest
julia> using Test, Logging

julia> f() = @info "Hi" number=5;

julia> test_logger = TestLogger();

julia> with_logger(test_logger) do
f()
@info "Bye!"
end

julia> @test test_logger.logs[1].message == "Hi"
Test Passed

julia> @test test_logger.logs[1].kwargs[:number] == 5
Test Passed

julia> @test test_logger.logs[2].message == "Bye!"
Test Passed
```
"""
TestLogger(; min_level=Info, catch_exceptions=false, respect_maxlog=true) =
TestLogger(LogRecord[], min_level, catch_exceptions, nothing, Dict{Any, Int}(), respect_maxlog)
Logging.min_enabled_level(logger::TestLogger) = logger.min_level
Expand Down