DetectLeaksAfterTestSuccess.kt
TLDR
This file contains the DetectLeaksAfterTestSuccess
class, which is a TestRule
that invokes the LeakAssertions.assertNoLeaks
method after a test successfully evaluates. This rule is typically used within a rule chain to detect different types of leaks.
Classes
DetectLeaksAfterTestSuccess
The DetectLeaksAfterTestSuccess
class is a TestRule
that invokes LeakAssertions.assertNoLeaks
after a test successfully evaluates. This rule is typically used within a rule chain to detect different types of leaks. It automatically applies the TestDescriptionHolder
rule.
Methods
This class has no methods.
package leakcanary
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
/**
* [TestRule] that invokes [LeakAssertions.assertNoLeaks] after the test
* successfully evaluates. Pay attention to where you set up this rule in the
* rule chain as you might detect different leaks (e.g. around vs wrapped by the
* activity rule). It's also possible to use this rule several times in a rule
* chain.
*
* This rule automatically applies the [TestDescriptionHolder] rule.
*/
class DetectLeaksAfterTestSuccess(
private val tag: String = DetectLeaksAfterTestSuccess::class.java.simpleName
) : TestRule {
override fun apply(base: Statement, description: Description): Statement {
return TestDescriptionHolder.wrap(object : Statement() {
override fun evaluate() {
try {
base.evaluate()
// If the test fails, evaluate() will throw and we won't run the analysis (which is good).
LeakAssertions.assertNoLeaks(tag)
} finally {
// Otherwise upstream test failures will be reported as leaks.
// https://github.com/square/leakcanary/issues/2297
AppWatcher.objectWatcher.clearWatchedObjects()
}
}
}, description)
}
companion object {
/**
* A helper function to trigger leak detection twice during test tear down, before and after
* the tear down of a set of wrapped rule chains. For example, this can be useful to detect
* leaks both right before and right after the activity under test is destroyed. Before means
* we can detect detached fragment leaks that go away when the activity is destroyed. After
* means we can detect activity leaks.
*
* ```kotlin
* RuleChain.outerRule(LoginRule())
* .detectLeaksAfterTestSuccessWrapping("ActivitiesDestroyed") {
* around(ActivityScenarioRule(MyActivity::class.java))
* }
* .around(LoadingScreenRule())
* ```
*/
fun RuleChain.detectLeaksAfterTestSuccessWrapping(
tag: String,
wrapped: RuleChain.() -> RuleChain
): RuleChain {
return around(DetectLeaksAfterTestSuccess("After$tag")).wrapped()
.around(DetectLeaksAfterTestSuccess("Before$tag"))
}
}
}