【问题标题】:How redirect Timber logs to Junit logcat如何将 Timber 日志重定向到 Junit logcat
【发布时间】:2020-03-21 15:09:36
【问题描述】:

我将 Timber 与 DebugTree 和 ProductionTree 一起使用。正在运行的应用程序中一切都很好。 我还成功地在我的 JUnit 测试实现中使用了 Timber,这很好(没有真正的好处,但它确实有效)。

但是,我想让 code under test 上的日志显示在 JUnit 日志中。

我尝试构建JUnitTree 并将木材原木重定向到println(…),并在@Before 函数中设置木材JUnitTree,但没有任何效果。社区有什么解决方案吗?

我的请求没有意义吗,我在网络上没有找到任何关于此需求的信息(可能我使用了错误的关键字)。

【问题讨论】:

标签: android kotlin junit logcat timber-android


【解决方案1】:

以下ConsoleTree 类可用于将 Timber 日志转发到标准输出:

class ConsoleTree : Timber.DebugTree() {

    @Language("RegExp")
    private val anonymousClassPattern = Pattern.compile("""(\$\d+)+$""")

    private val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")

    override fun log(priority: Int, tag: String?, message: String, throwable: Throwable?) {
        val dateTime = LocalDateTime.now().formatWith(dateTimeFormatter)
        val priorityChar = when (priority) {
            Log.VERBOSE -> 'V'
            Log.DEBUG -> 'D'
            Log.INFO -> 'I'
            Log.WARN -> 'W'
            Log.ERROR -> 'E'
            Log.ASSERT -> 'A'
            else -> '?'
        }

        println("$dateTime $priorityChar/$tag: $message")
    }

    override fun createStackElementTag(element: StackTraceElement): String? {
        val matcher = anonymousClassPattern.matcher(element.className)
        val tag = when {
            matcher.find() -> matcher.replaceAll("")
            else -> element.className
        }
        return tag.substringAfterLast('.')
    }
}

对于 JUnit 4,可以使用规则为每个测试自动植入和根除 ConsoleTree:

class TimberConsoleRule : TestRule {
    override fun apply(base: Statement, description: Description) =
        TimberConsoleStatement(base)
}

class TimberConsoleStatement constructor(private val baseStatement: Statement) : Statement() {

    private val consoleTree = ConsoleTree()

    override fun evaluate() {
        Timber.plant(consoleTree)
        try {
            baseStatement.evaluate()
        } finally {
            Timber.uproot(consoleTree)
        }
    }
}

对于 JUnit 5,您可以简单地使用以下 @TimberConsoleLog 注释来注释 JUnit 测试:

@ExtendWith(TimberConsoleExtension::class)
@Retention(RUNTIME)
annotation class TimberConsoleLog

class TimberConsoleExtension : BeforeAllCallback, AfterAllCallback {

    private val consoleTree = ConsoleTree()

    override fun beforeAll(context: ExtensionContext) =
        Timber.plant(consoleTree)

    override fun afterAll(context: ExtensionContext) = 
        Timber.uproot(consoleTree)
}

【讨论】:

  • 对于 JUnit 4,它就像一个魅力。只是一些调整,但它的工作!谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 2017-03-26
  • 2017-11-02
  • 1970-01-01
  • 2020-04-23
  • 2017-03-08
  • 1970-01-01
相关资源
最近更新 更多