mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-15 02:57:04 +05:30
feat(android): add a heap growth detection test
This commit is contained in:
parent
59acbe2a37
commit
83eb3c13b2
4 changed files with 85 additions and 0 deletions
|
@ -6,6 +6,8 @@
|
||||||
*/
|
*/
|
||||||
@file:Suppress("UnstableApiUsage")
|
@file:Suppress("UnstableApiUsage")
|
||||||
|
|
||||||
|
import dev.msfjarvis.claw.gradle.addTestDependencies
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("dev.msfjarvis.claw.android-application")
|
id("dev.msfjarvis.claw.android-application")
|
||||||
id("dev.msfjarvis.claw.rename-artifacts")
|
id("dev.msfjarvis.claw.rename-artifacts")
|
||||||
|
@ -14,6 +16,7 @@ plugins {
|
||||||
id("dev.msfjarvis.claw.sentry")
|
id("dev.msfjarvis.claw.sentry")
|
||||||
id("dev.msfjarvis.claw.versioning-plugin")
|
id("dev.msfjarvis.claw.versioning-plugin")
|
||||||
alias(libs.plugins.aboutlibraries)
|
alias(libs.plugins.aboutlibraries)
|
||||||
|
alias(libs.plugins.android.junit5)
|
||||||
alias(libs.plugins.anvil)
|
alias(libs.plugins.anvil)
|
||||||
alias(libs.plugins.modulegraphassert)
|
alias(libs.plugins.modulegraphassert)
|
||||||
alias(libs.plugins.whetstone)
|
alias(libs.plugins.whetstone)
|
||||||
|
@ -25,6 +28,7 @@ plugins {
|
||||||
android {
|
android {
|
||||||
namespace = "dev.msfjarvis.claw.android"
|
namespace = "dev.msfjarvis.claw.android"
|
||||||
defaultConfig.applicationId = "dev.msfjarvis.claw.android"
|
defaultConfig.applicationId = "dev.msfjarvis.claw.android"
|
||||||
|
defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
buildFeatures.compose = true
|
buildFeatures.compose = true
|
||||||
composeOptions {
|
composeOptions {
|
||||||
useLiveLiterals = false
|
useLiveLiterals = false
|
||||||
|
@ -113,4 +117,9 @@ dependencies {
|
||||||
implementation(projects.web)
|
implementation(projects.web)
|
||||||
|
|
||||||
kapt(libs.dagger.compiler)
|
kapt(libs.dagger.compiler)
|
||||||
|
|
||||||
|
addTestDependencies(project)
|
||||||
|
androidTestImplementation(libs.androidx.test.espresso.core)
|
||||||
|
androidTestImplementation(libs.androidx.test.uiautomator)
|
||||||
|
androidTestImplementation(libs.leakcanary.android.test)
|
||||||
}
|
}
|
||||||
|
|
13
android/src/androidTest/AndroidManifest.xml
Normal file
13
android/src/androidTest/AndroidManifest.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!--
|
||||||
|
~ Copyright © 2021-2024 Harsh Shandilya.
|
||||||
|
~ Use of this source code is governed by an MIT-style
|
||||||
|
~ license that can be found in the LICENSE file or at
|
||||||
|
~ https://opensource.org/licenses/MIT.
|
||||||
|
-->
|
||||||
|
<manifest
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<!-- Performing the heap growth analysis in process requires more heap. -->
|
||||||
|
<application
|
||||||
|
android:largeHeap="true"/>
|
||||||
|
</manifest>
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2024 Harsh Shandilya.
|
||||||
|
* Use of this source code is governed by an MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT.
|
||||||
|
*/
|
||||||
|
package dev.msfjarvis.claw.android
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.uiautomator.By
|
||||||
|
import androidx.test.uiautomator.BySelector
|
||||||
|
import androidx.test.uiautomator.UiDevice
|
||||||
|
import androidx.test.uiautomator.UiObject2
|
||||||
|
import androidx.test.uiautomator.Until
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import de.mannodermaus.junit5.ActivityScenarioExtension
|
||||||
|
import leakcanary.repeatingAndroidInProcessScenario
|
||||||
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension
|
||||||
|
import shark.ObjectGrowthDetector
|
||||||
|
import shark.forAndroidHeap
|
||||||
|
|
||||||
|
class HeapGrowthCheck {
|
||||||
|
@JvmField
|
||||||
|
@RegisterExtension
|
||||||
|
val scenarioExtension = ActivityScenarioExtension.launch<MainActivity>()
|
||||||
|
private val detector = ObjectGrowthDetector.forAndroidHeap().repeatingAndroidInProcessScenario()
|
||||||
|
private lateinit var device: UiDevice
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
fun setUp() {
|
||||||
|
val instrumentation = InstrumentationRegistry.getInstrumentation()
|
||||||
|
device = UiDevice.getInstance(instrumentation)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun verify_heap_growth() {
|
||||||
|
val heapGrowth = detector.findRepeatedlyGrowingObjects { device.exploreScreens() }
|
||||||
|
assertThat(heapGrowth.growingObjects).isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
fun UiDevice.exploreScreens() {
|
||||||
|
listOf("HOTTEST", "NEWEST", "SAVED").forEach { tag ->
|
||||||
|
waitForObject(By.res(tag)).click()
|
||||||
|
waitForIdle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun UiDevice.waitForObject(selector: BySelector, timeout: Long = 10_000L): UiObject2 {
|
||||||
|
if (wait(Until.hasObject(selector), timeout)) {
|
||||||
|
return findObject(selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
error("Object with selector [$selector] not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
[versions]
|
[versions]
|
||||||
aboutLibraries = "11.1.4"
|
aboutLibraries = "11.1.4"
|
||||||
agp = "8.5.0-beta01"
|
agp = "8.5.0-beta01"
|
||||||
|
android-junit5 = "1.10.0.0"
|
||||||
benchmark = "1.3.0-alpha04"
|
benchmark = "1.3.0-alpha04"
|
||||||
coil = "2.6.0"
|
coil = "2.6.0"
|
||||||
# @keep used for kotlinCompilerExtensionVersion
|
# @keep used for kotlinCompilerExtensionVersion
|
||||||
|
@ -12,6 +13,7 @@ junit = "5.10.2"
|
||||||
konvert = "3.2.0"
|
konvert = "3.2.0"
|
||||||
kotlin = "1.9.24"
|
kotlin = "1.9.24"
|
||||||
kotlinResult = "2.0.0"
|
kotlinResult = "2.0.0"
|
||||||
|
leakcanary = "3.0-alpha-4"
|
||||||
lifecycle = "2.8.0-rc01"
|
lifecycle = "2.8.0-rc01"
|
||||||
retrofit = "2.11.0"
|
retrofit = "2.11.0"
|
||||||
richtext = "1.0.0-alpha01"
|
richtext = "1.0.0-alpha01"
|
||||||
|
@ -89,6 +91,7 @@ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-c
|
||||||
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
|
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
|
||||||
kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" }
|
kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" }
|
||||||
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
|
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
|
||||||
|
leakcanary-android-test = { module = "com.squareup.leakcanary:leakcanary-android-test", version.ref = "leakcanary" }
|
||||||
material3-pulltorefresh = "eu.bambooapps:compose-material3-pullrefresh:1.1.1"
|
material3-pulltorefresh = "eu.bambooapps:compose-material3-pullrefresh:1.1.1"
|
||||||
napier = "io.github.aakira:napier:2.7.1"
|
napier = "io.github.aakira:napier:2.7.1"
|
||||||
okhttp-bom = "com.squareup.okhttp3:okhttp-bom:4.12.0"
|
okhttp-bom = "com.squareup.okhttp3:okhttp-bom:4.12.0"
|
||||||
|
@ -114,6 +117,7 @@ unfurl = "me.saket.unfurl:unfurl:1.7.0"
|
||||||
[plugins]
|
[plugins]
|
||||||
aboutlibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutLibraries" }
|
aboutlibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutLibraries" }
|
||||||
android-lint = { id = "com.android.lint", version.ref = "agp" }
|
android-lint = { id = "com.android.lint", version.ref = "agp" }
|
||||||
|
android-junit5 = { id = "de.mannodermaus.android-junit5", version.ref = "android-junit5" }
|
||||||
android-test = { id = "com.android.test", version.ref = "agp" }
|
android-test = { id = "com.android.test", version.ref = "agp" }
|
||||||
anvil = "com.squareup.anvil:2.5.0-beta09"
|
anvil = "com.squareup.anvil:2.5.0-beta09"
|
||||||
baselineprofile = { id = "androidx.baselineprofile", version.ref = "benchmark" }
|
baselineprofile = { id = "androidx.baselineprofile", version.ref = "benchmark" }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue