swift-log icon indicating copy to clipboard operation
swift-log copied to clipboard

bootstrapping in XCTestCase

Open tanner0101 opened this issue 5 years ago • 9 comments

LoggingSystem.bootstrap must only be called once per process. One might assume to bootstrap the logger in XCTestCase.setUp, but this can be called multiple times and will result in an assertion.

To get around this, a global lazy variable can be used that is asserted in each setUp method. It will only be run once, the first time it is accessed, allowing for logging to be configured in XCTests:

Declare the global variable like so:

let isLoggingConfigured: Bool = {
    LoggingSystem.bootstrap { label in
        var handler = StreamLogHandler.standardOutput(label: label)
        handler.logLevel = .debug
        return handler
    }
    return true
}()

Then, in your XCTestCases, use like so:

import XCTest

final class FooTests: XCTestCase {
    override func setUp() {
        XCTAssert(isLoggingConfigured)
        ...
    }
}

We should consider documenting this or providing some sort of helper.

tanner0101 avatar Jun 07 '19 19:06 tanner0101

Sounds good to me, would you have a moment PR such section into the README.md perhaps?

ktoso avatar Jul 10 '19 03:07 ktoso

But what if I want to test different LogHandlers with the LoggingSystem? Seems to be impossible for now 😢

maximkrouk avatar Apr 29 '20 22:04 maximkrouk

So I found a workaround in @testable import Logging, so LoggingSystem.internalBootstrap works and it seems to be a nice way to replace LoggingSystem's factory in tests 🌚

Btw you can find beta of my LoggingKit here 🙂

maximkrouk avatar Apr 30 '20 15:04 maximkrouk

@maximkrouk you can construct a logger with a backend explicitly:

let logger = Logger(label: "foo") { label in
    MyAwesomeBackend(label)
}

see docs.

weissi avatar May 01 '20 13:05 weissi

Does this solution apply when using SwiftLog in an iOS app and its test cases? I'm finding the host app bootstraps the logging system fine, but then when loading tests I get the second bootstrapping error. I have attempted to use the lazy global variable approach above, but and finding its not protecting the bootstrapping from attempting again.

leisurehound avatar Jun 26 '20 04:06 leisurehound

@leisurehound could you send us the code you use with the lazy global? That should work.

weissi avatar Jun 26 '20 10:06 weissi

sorry, I had an unrelated config issue that was causing this, once I fixed that the tests now run without double bootstrapping the logger. Sorry for the noise.

leisurehound avatar Jun 28 '20 05:06 leisurehound

Thanks for looping back, closing the ticket then 👍

ktoso avatar Jun 28 '20 09:06 ktoso

Actually, the original ticket stands as to documenting the pattern, so opening.

ktoso avatar Jun 28 '20 09:06 ktoso