Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(android): update robolectric #1820

Merged
merged 1 commit into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions android/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ androidx-junit = "1.1.5"
androidx-compose-ui = "1.4.3"
androidx-compose-material3 = "1.0.1"
androidx-runtime-android = "1.5.4"
androidx-espresso-core = "3.5.1"
androidx-espresso = "3.5.1"
androidx-fragment-ktx = "1.2.5"
androidx-annotation = "1.7.1"
androidx-test-rules = "1.5.0"
Expand All @@ -45,7 +45,7 @@ squareup-curtains = "1.2.5"
squareup-okhttp = "4.12.0"
squareup-okio = "3.7.0"
squareup-leakcanary = "2.14"
robolectric = "4.11.1"
robolectric = "4.14.1"
kolinx-binary-compatibility-validator = "0.13.2"
diffplug-spotless = "6.24.0"
compose-plugin = "1.5.11"
Expand All @@ -61,7 +61,7 @@ androidx-benchmark-junit4 = { module = "androidx.benchmark:benchmark-junit4", ve
androidx-benchmark-macro-junit4 = { module = "androidx.benchmark:benchmark-macro-junit4", version.ref = "androidx-benchmark-macro-junit4" }
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx-constraintlayout" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" }
androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso-core" }
androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }
androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "androidx-fragment-ktx" }
androidx-fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "androidx-fragment-ktx" }
androidx-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" }
Expand Down
2 changes: 2 additions & 0 deletions android/measure/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ android {

defaultConfig {
minSdk = 21
testOptions.targetSdk = 35
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["clearPackageData"] = "true"
consumerProguardFiles("consumer-rules.pro")
Expand Down Expand Up @@ -187,6 +188,7 @@ dependencies {
androidTestImplementation(libs.androidx.lifecycle.process)
androidTestImplementation(libs.androidx.lifecycle.common)
androidTestImplementation(libs.androidx.activity.compose)
androidTestImplementation(libs.androidx.fragment.ktx)
androidTestImplementation(libs.androidx.navigation.compose)
androidTestImplementation(libs.androidx.rules)
androidTestImplementation(libs.androidx.uiautomator)
Expand Down
20 changes: 16 additions & 4 deletions android/measure/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sh.measure.android.test">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<!--
Workaround required for running tests on API 30 devices.
See https://github.com/android/android-test/issues/743.
Version 1.3.1 of the AndroidX Test libraries remove the need for this workaround.
-->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application>
<activity android:name="sh.measure.android.TestActivity">

<!--
Permissions required to ensure the tests do not get blocked by
-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

<application
android:exported="false"
android:usesCleartextTraffic="true">
<activity
android:name="sh.measure.android.TestActivity"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Expand All @@ -21,5 +32,6 @@
-->
<meta-data android:name="sh.measure.android.API_URL" android:value="http://localhost:8080" />
</application>

</manifest>

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package sh.measure.android

import android.Manifest
import androidx.benchmark.junit4.PerfettoTraceRule
import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi
import android.util.Log
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.IdlingRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.GrantPermissionRule
import okhttp3.Headers
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
Expand Down Expand Up @@ -51,9 +51,12 @@ class EventsTest {
private val robot: EventsTestRobot = EventsTestRobot()
private val mockWebServer: MockWebServer = MockWebServer()

@OptIn(ExperimentalPerfettoCaptureApi::class)
@get:Rule
val perfettoRule = PerfettoTraceRule(enableUserspaceTracing = true)
val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.POST_NOTIFICATIONS,
Manifest.permission.READ_MEDIA_AUDIO,
)

@Before
fun setup() {
Expand Down Expand Up @@ -622,29 +625,21 @@ class EventsTest {

@Test
fun tracksCustomEvent() {
// Given
robot.initializeMeasure(MeasureConfig(enableLogging = true))
ActivityScenario.launch(TestActivity::class.java).use {
// When
robot.trackCustomEvent()
triggerExport()

// Then
assertEventTracked(EventType.CUSTOM)
}
}

@Test
fun tracksAttributesWithEvents() {
// Given
robot.initializeMeasure(MeasureConfig(enableLogging = true))
ActivityScenario.launch(TestActivity::class.java).use {
// When
robot.addAttribute("user_defined_attr_key", "user_defined_attr_value")
triggerExport()
Log.d("Test", "Starting tracksCustomEvent test")
try {
// Given
robot.initializeMeasure(MeasureConfig(enableLogging = true))
ActivityScenario.launch(TestActivity::class.java).use {
// When
robot.trackCustomEvent()
triggerExport()

// Then
assetAttribute("user_defined_attr_key", "user_defined_attr_value")
// Then
assertEventTracked(EventType.CUSTOM)
}
Log.d("Test", "Completed tracksCustomEvent test")
} catch (e: Exception) {
Log.e("Test", "Error tracksCustomEvent", e)
}
}

Expand Down Expand Up @@ -707,11 +702,6 @@ class EventsTest {
Assert.assertFalse(body.containsEvent(eventType))
}

private fun assetAttribute(key: String, value: String) {
val body = getLastRequestBody()
Assert.assertTrue(body.containsAttribute(key, value))
}

private fun getLastRequestBody(): String {
val request = mockWebServer.takeRequest(timeout = 1000, unit = TimeUnit.MILLISECONDS)
Assert.assertNotNull(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,4 @@ class EventsTestRobot {
}.build(),
)
}

fun addAttribute(key: String, value: String) {
Measure.addAttribute("user_defined_attr_key", "user_defined_attr_value")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import android.app.Application
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.NetworkInfo
import android.os.Build
import android.telephony.TelephonyManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RuntimeEnvironment
Expand Down Expand Up @@ -41,7 +43,11 @@ internal class InitialNetworkStateProviderTest {
@Test
fun `returns correct network generation with permission`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.READ_PHONE_STATE)
shadowOf(systemServiceProvider.telephonyManager).setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
shadowOf(systemServiceProvider.telephonyManager).setDataNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
} else {
shadowOf(systemServiceProvider.telephonyManager).setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
}

val networkGeneration = InitialNetworkStateProviderImpl(
context = context,
Expand Down Expand Up @@ -113,8 +119,8 @@ internal class InitialNetworkStateProviderTest {
assertNull(networkType)
}

@Suppress("DEPRECATION")
@Test
@Ignore("Specifying the SDK versions in @Config makes this test cause an OOM error after updating robolectric to 4.14")
@Config(sdk = [21])
fun `returns correct network type below API 23`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
Expand All @@ -130,8 +136,10 @@ internal class InitialNetworkStateProviderTest {
assertEquals(NetworkType.WIFI, networkType)
}

// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
// @Config(sdk = [23, 33])
@Test
@Config(sdk = [23, 33])
fun `returns correct network type above API 23`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
val nc = ShadowNetworkCapabilities.newInstance()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ class NetworkChangesCollectorTest {
telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
}

// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
// @Config(sdk = [23, 33])
@Test
@Config(sdk = [23, 24])
fun `NetworkChangesCollector does not register network callbacks if permission not available`() {
shadowOf(context as Application).denyPermissions(Manifest.permission.ACCESS_NETWORK_STATE)

Expand All @@ -65,8 +67,10 @@ class NetworkChangesCollectorTest {
Assert.assertEquals(0, shadowOf(connectivityManager).networkCallbacks.size)
}

@Test
// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
@Config(sdk = [21, 22])
@Test
fun `NetworkChangesCollector does not register network callbacks below API 23`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
NetworkChangesCollector(
Expand All @@ -81,8 +85,9 @@ class NetworkChangesCollectorTest {
Assert.assertEquals(0, shadowOf(connectivityManager).networkCallbacks.size)
}

// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
@Test
@Config(sdk = [23, 24, 26, 28, 29, 30, 31, 33])
fun `NetworkChangesCollector registers network callbacks when permission is available`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
NetworkChangesCollector(
Expand All @@ -97,8 +102,10 @@ class NetworkChangesCollectorTest {
Assert.assertEquals(1, shadowOf(connectivityManager).networkCallbacks.size)
}

// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
// @Config(sdk = [23, 33])
@Test
@Config(sdk = [23, 33])
fun `NetworkChangesCollector tracks change to cellular network with network_provider and network_generation`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
shadowOf(context as Application).grantPermissions(Manifest.permission.READ_PHONE_STATE)
Expand Down Expand Up @@ -135,8 +142,10 @@ class NetworkChangesCollectorTest {
)
}

@Test
// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
@Config(sdk = [23])
@Test
fun `NetworkChangesCollector tracks change to cellular network without network_generation if READ_PHONE_STATE permission is not available`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
shadowOf(telephonyManager).setNetworkOperatorName("Test Provider")
Expand Down Expand Up @@ -166,8 +175,10 @@ class NetworkChangesCollectorTest {
)
}

// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
// @Config(sdk = [33])
@Test
@Config(sdk = [33])
fun `NetworkChangesCollector tracks change to cellular network with network_provider & network_generation if READ_BASIC_PHONE_STATE permission is available`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
shadowOf(context as Application).grantPermissions(Manifest.permission.READ_BASIC_PHONE_STATE)
Expand Down Expand Up @@ -201,8 +212,10 @@ class NetworkChangesCollectorTest {
)
}

// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
// @Config(sdk = [26, 33])
@Test
@Config(sdk = [26, 33])
fun `NetworkChangesCollector discards first change for SDK 26 and above`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
shadowOf(context as Application).grantPermissions(Manifest.permission.READ_BASIC_PHONE_STATE)
Expand All @@ -223,8 +236,10 @@ class NetworkChangesCollectorTest {
Mockito.verifyNoInteractions(signalProcessor)
}

// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
// @Config(sdk = [23, 33])
@Test
@Config(sdk = [23, 33])
fun `NetworkChangesCollector updates network provider when network changes`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
shadowOf(context as Application).grantPermissions(Manifest.permission.READ_PHONE_STATE)
Expand Down Expand Up @@ -260,8 +275,8 @@ class NetworkChangesCollectorTest {
)
}

@Test
@Config(sdk = [23])
@Test
fun `NetworkChangesCollector tracks change to wifi network`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)

Expand Down Expand Up @@ -470,8 +485,10 @@ class NetworkChangesCollectorTest {
)
}

// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
// @Config(sdk = [23])
@Test
@Config(sdk = [23])
fun `NetworkChangesCollector updates network state provider when network is lost`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)

Expand All @@ -498,8 +515,10 @@ class NetworkChangesCollectorTest {
)
}

@Test
// Ideally we would like to test on multiple versions, but specifying the SDK versions
// in @Config makes this test cause an OOM error after updating robolectric to 4.14
@Config(sdk = [23])
@Test
fun `NetworkChangesCollector discards first change with previous network when network is lost`() {
shadowOf(context as Application).grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE)
shadowOf(context as Application).grantPermissions(Manifest.permission.READ_PHONE_STATE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,19 @@ import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import org.robolectric.Robolectric
import org.robolectric.annotation.Config
import sh.measure.android.TestLifecycleActivity
import sh.measure.android.fakes.FakeConfigProvider
import sh.measure.android.fakes.NoopLogger
import sh.measure.android.screenshot.ScreenshotCollectorImpl

@RunWith(AndroidJUnit4::class)
class ScreenshotHelperTest {
class ScreenshotCollectorTest {
private val logger = NoopLogger()
private val lowMemoryCheck = mock<LowMemoryCheck>()
private val config = FakeConfigProvider()
private val controller = Robolectric.buildActivity(TestLifecycleActivity::class.java)

@Test
@Config(sdk = [21, 33])
fun `returns screenshot when resumed activity is available`() {
val application =
InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as Application
Expand All @@ -43,7 +41,6 @@ class ScreenshotHelperTest {
}

@Test
@Config(sdk = [21, 33])
fun `returns null when resumed activity is not available`() {
val application =
InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as Application
Expand Down
Loading