运行 测试时如何禁用 Fabric

How to disable Fabric when running tests

如何在 运行 测试时禁用 Fabric: Crashlytics 和 Answer?

有没有其他方法可以在测试期间禁用 Crashlytics,而不是在每次测试之前都放置此代码?

@LargeTest
@RunWith(AndroidJUnit4::class)
class AcceptanceTest {
    @Before
    fun setUp() {
          val crashlyticsKit = Crashlytics.Builder()
            .core(CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
            .build()
          Fabric.with(InstrumentationRegistry.getContext(), crashlyticsKit)
    }

}

并避免放置像 IS_TEST_MODE

这样的全局布尔值

我找到了一种更好更简洁的方法来禁用和管理 Fabric。

在我的应用程序中我使用 slf4j-api,一个日志 API 在 web 开发中使用了很多。有了这个 API 你可以创建 appender,所以我决定创建一个 Fabric Appender 并且只在应用 运行.

时使用这个 appender

如何

安装 slf4jLogback

设置你的build.gradle

dependencies {
    ...
    // Log
    compile 'com.github.tony19:logback-android-core:1.1.1-6'
    compile 'com.github.tony19:logback-android-classic:1.1.1-6'
    compile 'org.slf4j:slf4j-api:1.7.21'
}

添加src/main/assets/logback.xml

<configuration>
    <appender name="FABRIC" class="path/to/your/FabricAppender" />
    <appender name="LOGCAT" class="ch.qos.logback.classic.android.LogcatAppender">
        <tagEncoder>
            <pattern>%logger{0}</pattern>
        </tagEncoder>
        <encoder>
            <pattern>[PUP] %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

<root level="INFO">
    <appender-ref ref="LOGCAT" />
    <appender-ref ref="FABRIC" />
</root>

默认情况下 Logback 有一个与 Logback 一起使用的自定义附加程序。可以评论FABRIC部分,我们稍后会解释。

添加src/androidTest/assets/logback.xml

<configuration>
    <appender name="LOGCAT" class="ch.qos.logback.classic.android.LogcatAppender">
        <tagEncoder>
            <pattern>%logger{0}</pattern>
        </tagEncoder>
        <encoder>
            <pattern>[PUP] %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="LOGCAT" />
    </root>
</configuration>

您不想在这里安装 Fabric appender!因为您只想使用 Logcat

进行仪器测试 运行ning

使用Logback

现在您可以使用 slf4j 的强大 API 轻松登录,如下所示

class MainActivity : AppCompatActivity() {
    private val log = LoggerFactory.getLogger(javaClass)!! // Call your logger in each class with this line

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        log.info("Activity start")
        // ...
    } }

Logback

设置面料

在您的项目中创建FabricAppender.kt

package your.package.log

import android.content.Context
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.classic.spi.ThrowableProxy
import ch.qos.logback.core.UnsynchronizedAppenderBase
import com.crashlytics.android.Crashlytics
import com.crashlytics.android.answers.Answers
import com.crashlytics.android.answers.CustomEvent
import io.fabric.sdk.android.Fabric

class FabricAppender : UnsynchronizedAppenderBase<ILoggingEvent>() {
    companion object {
        private var isFabricInit = false

        fun init(context: Context) {
            Fabric.with(context, Crashlytics(), Answers())
            isFabricInit = true
        }
    }

    override fun append(event: ILoggingEvent) {
        if (isFabricInit.not()) return
        when (event.level.levelInt) {
            Level.ERROR_INT -> {
                val throwable = (event.throwableProxy as ThrowableProxy).throwable
                if (throwable != null) {
                    Crashlytics.logException(throwable)
                } else {
                    Crashlytics.log(event.message.replace(": {}", ""))
                }
            }
        }
    }
}

每次调用 log.error("Something wrong happen!!") 时,此附加程序都会向 Crashlytics 发送异常。如您所见,您可以完全自定义 appender。

应用程序启动时初始化appender

class MainActivity : AppCompatActivity() {
    private val log = LoggerFactory.getLogger(javaClass)!! // Call your logger in each class with this line

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        FabricAppender.init(this) // Init before the first log

        log.info("Activity start")
        // ...
    } }

终于

现在,通过使用 slf4j API,您的结构将与您的代码完全隔离,并且在您的仪器测试 yataaa 期间不会使用!!!您可以在互联网上找到其他附加程序(发送到 ELK、文件等)

使用口味。

默认情况下,您有一个名为 main 的 flavor,您应该将在开发、测试和生产中使用的所有代码、资产和清单放在其中。您可以通过在模块的 build.gradle 文件中的 buildTypes { ... } 下添加您的风格名称来轻松创建新风格。这使您可以拆分依赖项并轻松删除发布版本中不需要甚至不需要的任何内容。您可以阅读更多关于口味 here 的内容。这样,您将能够分离主要风格中的核心代码,并仅在您的发布版本中添加 crashlytics。

例如,在你的主要口味中:

open class BaseApplication : Application()
{ 
    fun onCreate()
    {
       [common code between flavors]
    }
}

然后在你的版本中

open class MainApplication : BaseApplication()
{
    fun onCreate()
    {
      [initialize crashlytics]
    }
}

还有你的其他口味

open class MainApplication : BaseApplication()

注意:在清单中使用 MainApplication 而不是 BaseApplication

我们没有在每个 Espresso 测试中禁用它,而是在 运行 调试构建类型时避免启用它。

因此,在您的 Application class 中,像这样构建 Crashlytics 和 Answers:

CrashlyticsCore crashlyticsCore = new CrashlyticsCore.Builder()
    .disabled(BuildConfig.DEBUG)
    .build();

Fabric.with(this,
    new Crashlytics.Builder().core(crashlyticsCore).build(),
    new Answers());
}