diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3f9f620..57d5eda 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -50,7 +50,12 @@ android { getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) - signingConfig = signingConfigs.getByName("release") + signingConfig = signingConfigs.getByName("debug") + } + create("benchmark") { + initWith(buildTypes.getByName("release")) + matchingFallbacks += listOf("release") + isDebuggable = false } } compileOptions { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5bedad5..4da2097 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,8 +5,8 @@ + + + @@ -45,6 +50,7 @@ + + - + diff --git a/benchmark/benchmark-proguard-rules.pro b/benchmark/benchmark-proguard-rules.pro deleted file mode 100644 index e4061d2..0000000 --- a/benchmark/benchmark-proguard-rules.pro +++ /dev/null @@ -1,37 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile - --dontobfuscate - --ignorewarnings - --keepattributes *Annotation* - --dontnote junit.framework.** --dontnote junit.runner.** - --dontwarn androidx.test.** --dontwarn org.junit.** --dontwarn org.hamcrest.** --dontwarn com.squareup.javawriter.JavaWriter - --keepclasseswithmembers @org.junit.runner.RunWith public class * \ No newline at end of file diff --git a/benchmark/build.gradle.kts b/benchmark/build.gradle.kts index bf6445a..3478132 100644 --- a/benchmark/build.gradle.kts +++ b/benchmark/build.gradle.kts @@ -1,53 +1,53 @@ @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { - alias(libs.plugins.com.android.library) - alias(libs.plugins.androidx.benchmark) + alias(libs.plugins.androidTest) alias(libs.plugins.org.jetbrains.kotlin.android) } android { namespace = "com.yveskalume.eventcademy.benchmark" - compileSdk = 33 + compileSdk = 34 compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } + kotlinOptions { - jvmTarget = "17" + jvmTarget = "1.8" } defaultConfig { minSdk = 24 + targetSdk = 34 - testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } - testBuildType = "release" buildTypes { - debug { - // Since isDebuggable can"t be modified by gradle for library modules, - // it must be done in a manifest - see src/androidTest/AndroidManifest.xml - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "benchmark-proguard-rules.pro" - ) - } - release { - isDefault = true + // This benchmark buildType is used for benchmarking, and should function like your + // release build (for example, with minification on). It"s signed with a debug key + // for easy local/CI testing. + create("benchmark") { + isDebuggable = true + signingConfig = getByName("debug").signingConfig + matchingFallbacks += listOf("release") } } + + targetProjectPath = ":app" + experimentalProperties["android.experimental.self-instrumenting"] = true } dependencies { - androidTestImplementation(libs.runner) - androidTestImplementation(libs.androidx.test.ext.junit) - androidTestImplementation(libs.junit) - androidTestImplementation(libs.benchmark.junit4) - // Add your dependencies here. Note that you cannot benchmark code - // in an app module this way - you will need to move any code you - // want to benchmark to a library module: - // https://developer.android.com/studio/projects/android-library#Convert + implementation(libs.androidx.test.ext.junit) + implementation(libs.espresso.core) + implementation(libs.uiautomator) + implementation(libs.benchmark.macro.junit4) +} +androidComponents { + beforeVariants(selector().all()) { + it.enable = it.buildType == "benchmark" + } } \ No newline at end of file diff --git a/benchmark/src/androidTest/AndroidManifest.xml b/benchmark/src/androidTest/AndroidManifest.xml deleted file mode 100644 index 405595c..0000000 --- a/benchmark/src/androidTest/AndroidManifest.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/benchmark/src/androidTest/java/com/yveskalume/eventcademy/benchmark/ExampleBenchmark.kt b/benchmark/src/androidTest/java/com/yveskalume/eventcademy/benchmark/ExampleBenchmark.kt deleted file mode 100644 index b9cb48f..0000000 --- a/benchmark/src/androidTest/java/com/yveskalume/eventcademy/benchmark/ExampleBenchmark.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.yveskalume.eventcademy.benchmark - -import android.util.Log -import androidx.benchmark.junit4.BenchmarkRule -import androidx.benchmark.junit4.measureRepeated -import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Benchmark, which will execute on an Android device. - * - * The body of [BenchmarkRule.measureRepeated] is measured in a loop, and Studio will - * output the result. Modify your code to see how it affects performance. - */ -@RunWith(AndroidJUnit4::class) -class ExampleBenchmark { - - @get:Rule - val benchmarkRule = BenchmarkRule() - - @Test - fun log() { - benchmarkRule.measureRepeated { - Log.d("LogBenchmark", "the cost of writing this log method will be measured") - } - } -} \ No newline at end of file diff --git a/benchmark/src/main/AndroidManifest.xml b/benchmark/src/main/AndroidManifest.xml index 568741e..227314e 100644 --- a/benchmark/src/main/AndroidManifest.xml +++ b/benchmark/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - \ No newline at end of file diff --git a/benchmark/src/main/java/com/yveskalume/eventcademy/benchmark/StartupBenchmark.kt b/benchmark/src/main/java/com/yveskalume/eventcademy/benchmark/StartupBenchmark.kt new file mode 100644 index 0000000..d274ba7 --- /dev/null +++ b/benchmark/src/main/java/com/yveskalume/eventcademy/benchmark/StartupBenchmark.kt @@ -0,0 +1,38 @@ +package com.yveskalume.eventcademy.benchmark + +import androidx.benchmark.macro.StartupMode +import androidx.benchmark.macro.StartupTimingMetric +import androidx.benchmark.macro.junit4.MacrobenchmarkRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * This is an example startup benchmark. + * + * It navigates to the device's home screen, and launches the default activity. + * + * Before running this benchmark: + * 1) switch your app's active build variant in the Studio (affects Studio runs only) + * 2) add `` to your app's manifest, within the `` tag + * + * Run this benchmark from Studio to see startup measurements, and captured system traces + * for investigating your app's performance. + */ +@RunWith(AndroidJUnit4::class) +class StartupBenchmark { + @get:Rule + val benchmarkRule = MacrobenchmarkRule() + + @Test + fun startup() = benchmarkRule.measureRepeated( + packageName = "com.yveskalume.eventcademy", + metrics = listOf(StartupTimingMetric()), + iterations = 5, + startupMode = StartupMode.COLD + ) { + pressHome() + startActivityAndWait() + } +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 7dacc3d..28359b9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,6 +10,7 @@ plugins { alias(libs.plugins.org.jetbrains.kotlin.serialization) apply false alias(libs.plugins.com.android.library) apply false alias(libs.plugins.androidx.benchmark) apply false + alias(libs.plugins.androidTest) apply false } true // Needed to make the Suppress annotation work for the plugins block \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2e48ea6..454c785 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,6 +28,8 @@ com-google-android-material-material = "1.10.0" androidx-benchmark = "1.1.1" runner = "1.5.2" benchmark-junit4 = "1.2.0" +uiautomator = "2.2.0" +benchmark-macro-junit4 = "1.2.0-beta01" [libraries] androidx-core-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "core-splashscreen" } @@ -82,6 +84,8 @@ runner = { group = "androidx.test", name = "runner", version.ref = "runner" } benchmark-junit4 = { group = "androidx.benchmark", name = "benchmark-junit4", version.ref = "benchmark-junit4" } konfetti-compose = "nl.dionsegijn:konfetti-compose:2.0.3" +uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" } +benchmark-macro-junit4 = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "benchmark-macro-junit4" } [plugins] @@ -94,6 +98,7 @@ com-google-firebase-crashlytics = { id = "com.google.firebase.crashlytics", vers org-jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version = "1.7.10" } com-android-library = { id = "com.android.library", version.ref = "agp" } androidx-benchmark = { id = "androidx.benchmark", version.ref = "androidx-benchmark" } +androidTest = { id = "com.android.test", version.ref = "agp" } [bundles]