From f3f818fbed9c33cddc0049035143fd2db4f84902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Lo=CC=81pez=20Man=CC=83as?= Date: Mon, 28 Sep 2026 15:25:19 +0200 Subject: [PATCH] test: skip map instrumentation tests when no Maps API key is available The emulator suite fails on every Dependabot pull request, and on forks, for a reason that has nothing to do with the change under test: neither can read the repository secret that supplies the Maps API key. The workflow falls back to writing MAPS_API_KEY=YOUR_API_KEY, hasValidApiKey is then false, and the map-dependent tests hit check(hasValidApiKey) { "Maps API key not specified" }, which throws IllegalStateException and fails the build. On PR #1015 that was 29 of 41 tests; the 30th, StreetViewTests, has no guard at all and instead timed out waiting for a panorama that can never load. A test that cannot run for lack of a credential is a skipped test, not a failing one, so replace the check with a JUnit assumption via a shared assumeValidApiKey() helper, and add the missing guard to StreetViewTests. Two things worth knowing about the result: - Three tests declare @Test(expected = IllegalStateException::class) for marker-state reuse. Without a key they were being satisfied by the missing-key IllegalStateException itself, so they passed without ever exercising the reuse logic. JUnit 4.13.2 propagates assumption failures through the expected-exception check, so they now skip when no key is present and assert for real when one is. - AGP writes assumption failures into the connected-test XML as with skipped="0", so the generated report still reads "33 failures" even though the task passes. The count is cosmetic; the build result is not. Verified on an API 30 emulator: with MAPS_API_KEY=YOUR_API_KEY the task succeeds with all 33 results recorded as AssumptionViolatedException, and with a real key 39 of 41 tests pass. The two that fail, GoogleMapViewTests.testStartingCameraPosition and MapInColumnTests.testScrollColumn_MapCameraRemainsSame, fail identically on main and are unrelated to this change. --- .../android/compose/GoogleMapFocusTraversalTests.kt | 4 ++-- .../android/compose/GoogleMapViewClusteringTests.kt | 2 +- .../maps/android/compose/GoogleMapViewTests.kt | 2 +- .../google/maps/android/compose/MapInColumnTests.kt | 2 +- .../maps/android/compose/MapsInLazyColumnTest.kt | 2 +- .../android/compose/RecompositionActivityTests.kt | 2 +- .../com/google/maps/android/compose/ScaleBarTests.kt | 2 +- .../google/maps/android/compose/StreetViewTests.kt | 2 ++ .../com/google/maps/android/compose/TestUtils.kt | 12 ++++++++++++ 9 files changed, 22 insertions(+), 8 deletions(-) diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapFocusTraversalTests.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapFocusTraversalTests.kt index 3c6dea96d..b64b95ecd 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapFocusTraversalTests.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapFocusTraversalTests.kt @@ -52,7 +52,7 @@ class GoogleMapFocusTraversalTests { ) private fun initMaps() { - check(hasValidApiKey) { "Maps API key not specified" } + assumeValidApiKey() composeTestRule.setContent { MapsInLazyColumn( @@ -89,7 +89,7 @@ class GoogleMapFocusTraversalTests { @OptIn(ExperimentalTestApi::class) @Test fun nonFocusableMapIsSkippedDuringTabTraversal() { - check(hasValidApiKey) { "Maps API key not specified" } + assumeValidApiKey() composeTestRule.setContent { Column { diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapViewClusteringTests.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapViewClusteringTests.kt index d4807c3ca..9e231c12a 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapViewClusteringTests.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapViewClusteringTests.kt @@ -59,7 +59,7 @@ class GoogleMapViewClusteringTests { clusterManagerHolder: Array?>, content: @Composable () -> Unit ): Marker { - check(hasValidApiKey) { "Maps API key not specified" } + assumeValidApiKey() val countDownLatch = CountDownLatch(1) composeTestRule.setContent { diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapViewTests.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapViewTests.kt index 25f24d635..9ef1dde58 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapViewTests.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/GoogleMapViewTests.kt @@ -53,7 +53,7 @@ class GoogleMapViewTests { private var mapColorScheme = ComposeMapColorScheme.FOLLOW_SYSTEM private fun initMap(content: @Composable () -> Unit = {}) { - check(hasValidApiKey) { "Maps API key not specified" } + assumeValidApiKey() val countDownLatch = CountDownLatch(1) val appContext: Context = InstrumentationRegistry.getInstrumentation().targetContext diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/MapInColumnTests.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/MapInColumnTests.kt index 760364411..b03fc2674 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/MapInColumnTests.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/MapInColumnTests.kt @@ -40,7 +40,7 @@ class MapInColumnTests { private lateinit var cameraPositionState: CameraPositionState private fun initMap() { - check(hasValidApiKey) { "Maps API key not specified" } + assumeValidApiKey() val countDownLatch = CountDownLatch(1) composeTestRule.setContent { var scrollingEnabled by remember { mutableStateOf(true) } diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/MapsInLazyColumnTest.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/MapsInLazyColumnTest.kt index 7ec24aff9..4f6152e22 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/MapsInLazyColumnTest.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/MapsInLazyColumnTest.kt @@ -58,7 +58,7 @@ class MapsInLazyColumnTests { private lateinit var cameraPositionStates: Map private fun initMaps() { - check(hasValidApiKey) { "Maps API key not specified" } + assumeValidApiKey() composeTestRule.setContent { val lazyListState = rememberLazyListState() diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/RecompositionActivityTests.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/RecompositionActivityTests.kt index fc5d4e2b6..b5692a386 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/RecompositionActivityTests.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/RecompositionActivityTests.kt @@ -31,7 +31,7 @@ class RecompositionActivityTests { @Test fun testChangeLocationButton_MovesCameraToNewLocation() { - check(hasValidApiKey) { "Maps API key not specified" } + assumeValidApiKey() val initialPosition = singapore val cameraPositionState = CameraPositionState( position = CameraPosition.fromLatLngZoom(initialPosition, 11f) diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/ScaleBarTests.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/ScaleBarTests.kt index fe55c3a5f..b859b8fb5 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/ScaleBarTests.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/ScaleBarTests.kt @@ -49,7 +49,7 @@ class ScaleBarTests { private lateinit var density: Density private fun initScaleBar(initialZoom: Float, initialPosition: LatLng) { - check(hasValidApiKey) { "Maps API key not specified" } + assumeValidApiKey() val countDownLatch = CountDownLatch(1) diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/StreetViewTests.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/StreetViewTests.kt index ed5b3fc3a..fae84065c 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/StreetViewTests.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/StreetViewTests.kt @@ -43,6 +43,8 @@ class StreetViewTests { @OptIn(MapsExperimentalFeature::class) private fun initStreetView(onClick: (StreetViewPanoramaOrientation) -> Unit = {}) { + assumeValidApiKey() + composeTestRule.setContent { StreetView( Modifier.semantics { contentDescription = "StreetView" }, diff --git a/maps-app/src/androidTest/java/com/google/maps/android/compose/TestUtils.kt b/maps-app/src/androidTest/java/com/google/maps/android/compose/TestUtils.kt index e9b74f011..eb732b851 100644 --- a/maps-app/src/androidTest/java/com/google/maps/android/compose/TestUtils.kt +++ b/maps-app/src/androidTest/java/com/google/maps/android/compose/TestUtils.kt @@ -18,6 +18,7 @@ package com.google.maps.android.compose import com.google.android.gms.maps.model.LatLng import org.junit.Assert.assertEquals +import org.junit.Assume.assumeTrue const val timeout2 = 2_000L const val timeout3 = 3_000L const val timeout5 = 5_000L @@ -26,6 +27,17 @@ const val MAP_LOAD_TIMEOUT_SECONDS = 30L val hasValidApiKey: Boolean = BuildConfig.MAPS_API_KEY.isNotBlank() && BuildConfig.MAPS_API_KEY != "YOUR_API_KEY" +/** + * Skips the calling test unless a real Maps API key is configured. + * + * Without a key the map never loads, so these tests have nothing to assert. Treating that as a + * skipped test rather than a failure keeps the build honest on forks and on Dependabot pull + * requests, neither of which can read the repository secret that supplies the key. + */ +fun assumeValidApiKey() { + assumeTrue("Maps API key not specified", hasValidApiKey) +} + const val assertRoundingError: Double = 0.01 fun LatLng.assertEquals(other: LatLng) {