Skip to content

Commit

Permalink
Improved speed of instrumentation tests on CI
Browse files Browse the repository at this point in the history
  • Loading branch information
LachlanMcKee committed Sep 2, 2023
1 parent 8ee078e commit db79e72
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 53 deletions.
74 changes: 39 additions & 35 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,56 +86,60 @@ jobs:
- uses: gradle/gradle-build-action@v2
with:
cache-read-only: ${{ env.MAIN_BRANCH != 'true' }}
- name: Pre build sources before launching emulator
run: ./gradlew compileDebugAndroidTestSources
- name: AVD cache
uses: actions/cache@v3
id: avd-cache
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Instrumentation tests
# Flags from https://github.com/android/nowinandroid/blob/main/.github/workflows/Build.yaml
run: >
adb logcat > logcat.out &
./gradlew packageDebugAndroidTest &&
./gradlew cleanManagedDevices --unused-only &&
./gradlew uiTestsDeviceDebugAndroidTest
-Dorg.gradle.workers.max=1
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
-Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true
- name: Upload failed instrumentation artifacts
if: failure()
uses: actions/upload-artifact@v2
with:
name: instrumentation-failures
path: |
~/.android/avd/*
~/.android/adb*
key: avd-29
- name: Create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
**/build/reports
logcat.out
screenshot-tests:
name: Screenshot tests
runs-on: macOS-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
# Use API 29 https://github.com/ReactiveCircus/android-emulator-runner/issues/222
api-level: 29
arch: x86_64
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
script: echo "Generated AVD snapshot for caching."
- name: Instrumentation tests
uses: reactivecircus/android-emulator-runner@v2
distribution: 'zulu'
java-version: '17'
- uses: gradle/wrapper-validation-action@v1
- uses: gradle/gradle-build-action@v2
with:
# Use API 29 https://github.com/ReactiveCircus/android-emulator-runner/issues/222
api-level: 29
arch: x86_64
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: |
adb logcat > logcat.out &
./gradlew connectedCheck
- name: Managed device clean-up
run: >
./gradlew cleanManagedDevices --unused-only
cache-read-only: ${{ env.MAIN_BRANCH != 'true' }}
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Screenshot tests
# Flags from https://github.com/android/nowinandroid/blob/main/.github/workflows/AndroidCIWithGmd.yaml
# Flags from https://github.com/android/nowinandroid/blob/main/.github/workflows/Build.yaml
run: >
adb logcat > logcat.out &
./gradlew cleanManagedDevices --unused-only &&
./gradlew screenshotTestsCompareBaseline
-Dorg.gradle.workers.max=1
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
-Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true
- name: Upload failed instrumentation artifacts
- name: Upload failed screenshot artifacts
if: failure()
uses: actions/upload-artifact@v2
with:
name: instrumentation-failures
name: screenshot-failures
path: |
**/build/reports
**/build/outputs/managed_device_android_test_additional_output
logcat.out
check-documentation:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package com.bumble.appyx.android

import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.DefaultConfig
import com.android.build.api.dsl.ManagedVirtualDevice
import com.android.build.api.variant.AndroidComponentsExtension
import com.bumble.appyx.versionCatalog
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.register

internal inline fun <
reified ConfigT : DefaultConfig,
Expand Down Expand Up @@ -60,6 +62,7 @@ private fun <DefaultConfigT : DefaultConfig> CommonExtension<*, *, DefaultConfig
useSupportLibrary = true
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["useTestStorageService"] = "true"
}

val composeEnabled = appyxExtension.buildFeatures.compose.get()
Expand All @@ -77,6 +80,12 @@ private fun <DefaultConfigT : DefaultConfig> CommonExtension<*, *, DefaultConfig
unitTests.all {
it.useJUnitPlatform()
}
managedDevices.devices.register<ManagedVirtualDevice>("uiTestsDevice") {
device = "Pixel"
@Suppress("MagicNumber")
apiLevel = 30
systemImageSource = "aosp-atd"
}
}

packagingOptions {
Expand Down
21 changes: 3 additions & 18 deletions plugins/screenshot-tests/src/main/kotlin/ScreenshotTestPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,40 +1,25 @@
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.ManagedVirtualDevice
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.register

class ScreenshotTestPlugin : Plugin<Project> {

override fun apply(target: Project) {
target.extensions.configure(CommonExtension::class.java) {
defaultConfig {
testInstrumentationRunnerArguments["useTestStorageService"] = "true"
}
testOptions.managedDevices.devices.register<ManagedVirtualDevice>(DEVICE_NAME) {
device = "Pixel"
@Suppress("MagicNumber")
apiLevel = 30
systemImageSource = "aosp"
}
}

target.dependencies.add(
"androidTestUtil",
target.extensions.getByType(VersionCatalogsExtension::class.java).named("libs")
.findLibrary("androidx-test-utils").get()
)

target.tasks.register(TASK_RECORD, RecordScreenshotsTask::class.java) {
dependsOn(project.tasks.named("${DEVICE_NAME}Check"))
dependsOn(project.tasks.named("${DEVICE_NAME}DebugAndroidTest"))
testResultsFolder.set(
project.file("build/outputs/managed_device_android_test_additional_output/debug/$DEVICE_NAME")
)
}

target.tasks.register(TASK_COMPARE, CompareScreenshotsTask::class.java) {
dependsOn(project.tasks.named("${DEVICE_NAME}Check"))
dependsOn(project.tasks.named("${DEVICE_NAME}DebugAndroidTest"))
testResultsFolder.set(
project.file("build/outputs/managed_device_android_test_additional_output/debug/$DEVICE_NAME")
)
Expand All @@ -43,7 +28,7 @@ class ScreenshotTestPlugin : Plugin<Project> {
}

companion object {
const val DEVICE_NAME = "screenshotTestsDevice"
const val DEVICE_NAME = "uiTestsDevice"
const val GROUP = "screenshot-tests"
const val TASK_COMPARE = "screenshotTestsCompareBaseline"
const val TASK_RECORD = "screenshotTestsRecordBaseline"
Expand Down

0 comments on commit db79e72

Please sign in to comment.