[#525] Refactoring Integration Test Module
* [#525] Refactoring Integration Test Module - Change module type to test + related Gradle scripts change - Rename module to - remove the trailing Lib suffix + documentation - Move module structure from test to main source * Static checks result fix * Temporary enable FTL test * Test updated emulator.wft version * Update locked emulator.wtf dependency version * Enable emulator.wft tests for ui-integration-test module on CI * Fix enable emulator.wft tests for ui-integration-test module on CI - Update documentation * Test Fladle configuration for ui-integration-test module * Fix Fladle for ui-integration-test module * Rename ui-integration-test module flade configuration * Disable again FTL action from PRs * Clear support for FTL from ui-integration-test module * Refactor the emulator.wtf support across our modules. * Fix Mermaid graph syntax * Minor change in comment * Fix ui-integration-test module run configuration - Fixed manually - Aligned with other run configurations - Stable and beta versions of AS behave differentially, but after this fix it seems to be working as expected in both * Update emulator.wtf run configuration - Covered ui-integration-test module too - Changed configuration name
This commit is contained in:
parent
3d1d8fd363
commit
bffa5870b6
|
@ -294,7 +294,7 @@ jobs:
|
|||
ORG_GRADLE_PROJECT_ZCASH_DEBUG_APP_NAME_SUFFIX: ""
|
||||
ORG_GRADLE_PROJECT_ZCASH_EMULATOR_WTF_API_KEY: ${{ secrets.EMULATOR_WTF_API_KEY }}
|
||||
run: |
|
||||
./gradlew testDebugWithEmulatorWtf :app:testZcashmainnetDebugWithEmulatorWtf
|
||||
./gradlew testDebugWithEmulatorWtf :app:testZcashmainnetDebugWithEmulatorWtf :ui-integration-test:testZcashmainnetDebugWithEmulatorWtf
|
||||
- name: Collect Artifacts
|
||||
if: ${{ always() }}
|
||||
timeout-minutes: 1
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="testDebugWithEmulatorWtf :app:testZcashmainnetDebugWithEmulatorWtf" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<configuration default="false" name="testOnEmulatorWtf" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="testDebugWithEmulatorWtf :app:testZcashmainnetDebugWithEmulatorWtf" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list />
|
||||
<list>
|
||||
<option value="testDebugWithEmulatorWtf" />
|
||||
<option value=":app:testZcashmainnetDebugWithEmulatorWtf" />
|
||||
<option value=":ui-integration-test:testZcashmainnetDebugWithEmulatorWtf" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
|
@ -1,6 +1,6 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="ui-integration-test:connectedCheck" type="AndroidTestRunConfigurationType" factoryName="Android Instrumented Tests">
|
||||
<module name="zcash-android-app.ui-integration-test-lib" />
|
||||
<module name="zcash-android-app.ui-integration-test" />
|
||||
<option name="TESTING_TYPE" value="0" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="CLASS_NAME" value="" />
|
||||
|
@ -13,6 +13,8 @@
|
|||
<option name="RETENTION_COMPRESS_SNAPSHOTS" value="false" />
|
||||
<option name="CLEAR_LOGCAT" value="false" />
|
||||
<option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
|
||||
<option name="SKIP_NOOP_APK_INSTALLATIONS" value="true" />
|
||||
<option name="FORCE_STOP_RUNNING_APP" value="true" />
|
||||
<option name="INSPECTION_WITHOUT_ACTIVITY_RESTART" value="false" />
|
||||
<option name="TARGET_SELECTION_MODE" value="DEVICE_AND_SNAPSHOT_COMBO_BOX" />
|
||||
<option name="SELECTED_CLOUD_MATRIX_CONFIGURATION_ID" value="-1" />
|
||||
|
|
|
@ -315,27 +315,4 @@ fladle {
|
|||
|
||||
emulatorwtf {
|
||||
directoriesToPull.set(listOf("/sdcard/googletest/test_outputfiles"))
|
||||
|
||||
val appMinSdkVersion = run {
|
||||
@Suppress("MagicNumber", "PropertyName", "VariableNaming")
|
||||
val EMULATOR_WTF_MIN_SDK = 23
|
||||
|
||||
val buildMinSdk = project.properties["ANDROID_APP_MIN_SDK_VERSION"].toString().toInt()
|
||||
buildMinSdk.coerceAtLeast(EMULATOR_WTF_MIN_SDK).toString()
|
||||
}
|
||||
|
||||
val targetSdkVersion = run {
|
||||
@Suppress("MagicNumber", "PropertyName", "VariableNaming")
|
||||
val EMULATOR_WTF_MAX_SDK = 31
|
||||
|
||||
val buildTargetSdk = project.properties["ANDROID_TARGET_SDK_VERSION"].toString().toInt()
|
||||
buildTargetSdk.coerceAtMost(EMULATOR_WTF_MAX_SDK).toString()
|
||||
}
|
||||
|
||||
devices.set(
|
||||
listOf(
|
||||
mapOf("model" to "Pixel2", "version" to appMinSdkVersion),
|
||||
mapOf("model" to "Pixel2", "version" to targetSdkVersion)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ org.ow2.asm:asm-util:9.1=runtimeClasspath
|
|||
org.ow2.asm:asm:9.1=compileClasspath,runtimeClasspath
|
||||
org.slf4j:slf4j-api:1.7.30=runtimeClasspath
|
||||
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=runtimeClasspath
|
||||
wtf.emulator:gradle-plugin:0.0.10=compileClasspath,runtimeClasspath
|
||||
wtf.emulator:gradle-plugin:0.0.12=compileClasspath,runtimeClasspath
|
||||
xerces:xercesImpl:2.12.0=runtimeClasspath
|
||||
xml-apis:xml-apis:1.4.01=runtimeClasspath
|
||||
empty=annotationProcessor
|
||||
|
|
|
@ -52,6 +52,28 @@ pluginManager.withPlugin("com.android.library") {
|
|||
}
|
||||
}
|
||||
|
||||
pluginManager.withPlugin("com.android.test") {
|
||||
project.the<com.android.build.gradle.TestExtension>().apply {
|
||||
configureBaseExtension(isLibrary = true)
|
||||
|
||||
defaultConfig {
|
||||
minSdk = project.property("ANDROID_LIB_MIN_SDK_VERSION").toString().toInt()
|
||||
targetSdk = project.property("ANDROID_TARGET_SDK_VERSION").toString().toInt()
|
||||
|
||||
// The last two are for support of pseudolocales in debug builds.
|
||||
// If we add other localizations, they should be included in this list.
|
||||
// By explicitly setting supported locales, we strip out unused localizations from third party
|
||||
// libraries (e.g. play services)
|
||||
resourceConfigurations.addAll(listOf("en", "en-rUS", "en-rGB", "en-rAU", "en_XA", "ar_XB"))
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
testCoverage {
|
||||
jacocoVersion = project.property("JACOCO_VERSION").toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
fun com.android.build.gradle.BaseExtension.configureBaseExtension(isLibrary: Boolean) {
|
||||
compileSdkVersion(project.property("ANDROID_COMPILE_SDK_VERSION").toString().toInt())
|
||||
|
|
|
@ -7,6 +7,8 @@ val EMULATOR_WTF_MIN_SDK = 23
|
|||
@Suppress("MagicNumber", "PropertyName", "VariableNaming")
|
||||
val EMULATOR_WTF_MAX_SDK = 31
|
||||
|
||||
internal val className = this::class.simpleName
|
||||
|
||||
pluginManager.withPlugin("wtf.emulator.gradle") {
|
||||
project.the<wtf.emulator.EwExtension>().apply {
|
||||
val tokenString = project.properties["ZCASH_EMULATOR_WTF_API_KEY"].toString()
|
||||
|
@ -14,8 +16,18 @@ pluginManager.withPlugin("wtf.emulator.gradle") {
|
|||
token.set(tokenString)
|
||||
}
|
||||
|
||||
val libraryMinSdkVersion = run {
|
||||
val buildMinSdk = project.properties["ANDROID_LIB_MIN_SDK_VERSION"].toString().toInt()
|
||||
val buildMinSdk = if (pluginManager.hasPlugin("com.android.application")) {
|
||||
project.properties["ANDROID_APP_MIN_SDK_VERSION"].toString().toInt()
|
||||
} else if (pluginManager.hasPlugin("com.android.test")) {
|
||||
project.properties["ANDROID_APP_MIN_SDK_VERSION"].toString().toInt()
|
||||
} else if (pluginManager.hasPlugin("com.android.library")) {
|
||||
project.properties["ANDROID_LIB_MIN_SDK_VERSION"].toString().toInt()
|
||||
} else {
|
||||
throw IllegalArgumentException("Unsupported plugin type. Make sure that the plugin type you've added is" +
|
||||
" supported by ${this.javaClass.name}.")
|
||||
}
|
||||
|
||||
val moduleMinSdkVersion = run {
|
||||
buildMinSdk.coerceAtLeast(EMULATOR_WTF_MIN_SDK).toString()
|
||||
}
|
||||
val targetSdkVersion = run {
|
||||
|
@ -25,7 +37,7 @@ pluginManager.withPlugin("wtf.emulator.gradle") {
|
|||
|
||||
devices.set(
|
||||
listOf(
|
||||
mapOf("model" to "Pixel2", "version" to libraryMinSdkVersion),
|
||||
mapOf("model" to "Pixel2", "version" to moduleMinSdkVersion),
|
||||
mapOf("model" to "Pixel2", "version" to targetSdkVersion)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -132,7 +132,7 @@ kover {
|
|||
"spackle-android-lib",
|
||||
"test-lib",
|
||||
"ui-design-lib",
|
||||
"ui-integration-test-lib",
|
||||
"ui-integration-test",
|
||||
"ui-lib",
|
||||
)
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ org.ow2.asm:asm-util:9.1=classpath
|
|||
org.ow2.asm:asm:9.1=classpath
|
||||
org.slf4j:slf4j-api:1.7.30=classpath
|
||||
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
|
||||
wtf.emulator:gradle-plugin:0.0.10=classpath
|
||||
wtf.emulator:gradle-plugin:0.0.12=classpath
|
||||
xerces:xercesImpl:2.12.0=classpath
|
||||
xml-apis:xml-apis:1.4.01=classpath
|
||||
xmlpull:xmlpull:1.1.3.1=classpath
|
||||
|
|
|
@ -32,7 +32,7 @@ The logical components of the app are implemented as a number of Gradle modules.
|
|||
* ui
|
||||
* `ui-design` — Contains UI theme elements only. Besides offering modularization, this allows for hiding of some Material Design components behind our own custom components.
|
||||
* `ui-lib` — User interface that the user interacts with. This contains 99% of the UI code, along with localizations, icons, and other assets.
|
||||
* `ui-integration-test-lib` — Is dedicated for integration tests only. It has Android Test Orchestrator turned on — it allows us to run each of our tests within its own invocation of Instrumentation, and thus brings us benefits for the testing environment (minimal shared state, crashes are isolated, permissions are reset).
|
||||
* `ui-integration-test` — Is a pure test module dedicated for integration tests only. It has Android Test Orchestrator turned on — it allows us to run each of our tests within its own invocation of Instrumentation, and thus brings us benefits for the testing environment (minimal shared state, crashes are isolated, permissions are reset).
|
||||
* preference
|
||||
* `preference-api-lib` — Multiplatform interfaces for key-value storage of preferences.
|
||||
* `preference-impl-android-lib` — Android-specific implementation for preference storage.
|
||||
|
@ -68,11 +68,11 @@ The following diagram shows a rough depiction of dependencies between the module
|
|||
subgraph ui
|
||||
uiDesignLib[[ui-design-lib]];
|
||||
uiLib[[ui-lib]];
|
||||
uiIntegrationTestLib[[ui-integration-test-lib]];
|
||||
uiIntegrationTest[[ui-integration-test]];
|
||||
end
|
||||
uiDesignLib[[ui-design-lib]] --> uiLib[[ui-lib]];
|
||||
uiLib[[ui-lib]] --> uiIntegrationTestLib[[ui-integration-test-lib]];
|
||||
uiDesignLib[[ui-design-lib]] -- > uiIntegrationTestLib[[ui-integration-test-lib]];
|
||||
uiLib[[ui-lib]] --> uiIntegrationTest[[ui-integration-test]];
|
||||
uiDesignLib[[ui-design-lib]] --> uiIntegrationTest[[ui-integration-test]];
|
||||
subgraph spackle
|
||||
spackleLib[[spackle-lib]];
|
||||
spackleAndroidLib[[spackle-android-lib]];
|
||||
|
|
|
@ -160,7 +160,7 @@ For Continuous Integration, see [CI.md](CI.md). The rest of this section is reg
|
|||
1. If you are an Electric Coin Co team member: We are still setting up a process for this, because emulator.wtf does not yet support individual API tokens
|
||||
1. If you are an open source contributor: Visit http://emulator.wtf and request an API key
|
||||
1. Set the emulator.wtf API key as a global Gradle property `ZCASH_EMULATOR_WTF_API_KEY` under `~/.gradle/gradle.properties`
|
||||
1. Run the Gradle task `./gradlew testDebugWithEmulatorWtf :app:testZcashmainnetDebugWithEmulatorWtf` (emulator.wtf tasks do build the app, so you don't need to build them beforehand)
|
||||
1. Run the Gradle task `./gradlew testDebugWithEmulatorWtf :app:testZcashmainnetDebugWithEmulatorWtf :ui-integration-test:testZcashmainnetDebugWithEmulatorWtf` (emulator.wtf tasks do build the app, so you don't need to build them beforehand)
|
||||
|
||||
## Testnet funds
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ ANDROID_NDK_VERSION=23.0.7599858
|
|||
|
||||
ANDROID_GRADLE_PLUGIN_VERSION=7.3.0
|
||||
DETEKT_VERSION=1.21.0
|
||||
EMULATOR_WTF_GRADLE_PLUGIN_VERSION=0.0.10
|
||||
EMULATOR_WTF_GRADLE_PLUGIN_VERSION=0.0.12
|
||||
FLANK_VERSION=21.09.0
|
||||
FULLADLE_VERSION=0.17.4
|
||||
GRADLE_VERSIONS_PLUGIN_VERSION=0.42.0
|
||||
|
|
|
@ -43,6 +43,7 @@ pluginManagement {
|
|||
|
||||
id("com.android.application") version (androidGradlePluginVersion) apply (false)
|
||||
id("com.android.library") version (androidGradlePluginVersion) apply (false)
|
||||
id("com.android.test") version (androidGradlePluginVersion) apply (false)
|
||||
id("com.github.ben-manes.versions") version (extra["GRADLE_VERSIONS_PLUGIN_VERSION"].toString()) apply (false)
|
||||
id("com.github.triplet.play") version (extra["PLAY_PUBLISHER_PLUGIN_VERSION"].toString()) apply (false)
|
||||
id("com.osacky.fulladle") version (extra["FULLADLE_VERSION"].toString()) apply (false)
|
||||
|
@ -270,7 +271,7 @@ include("spackle-lib")
|
|||
include("spackle-android-lib")
|
||||
include("test-lib")
|
||||
include("ui-design-lib")
|
||||
include("ui-integration-test-lib")
|
||||
include("ui-integration-test")
|
||||
include("ui-lib")
|
||||
|
||||
val zcashSdkIncludedBuildPath = extra["SDK_INCLUDED_BUILD_PATH"].toString()
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest />
|
||||
|
|
@ -1,16 +1,20 @@
|
|||
plugins {
|
||||
id("com.android.library")
|
||||
id("com.android.test")
|
||||
kotlin("android")
|
||||
id("secant.android-build-conventions")
|
||||
id("wtf.emulator.gradle")
|
||||
id("secant.emulator-wtf-conventions")
|
||||
}
|
||||
|
||||
// Force orchestrator to be used for this module, because we need cleared state to generate screenshots
|
||||
// Force orchestrator to be used for this module, because we need cleared state before each test
|
||||
val isOrchestratorEnabled = true
|
||||
|
||||
android {
|
||||
namespace = "co.electriccoin.zcash.ui.integration"
|
||||
// Target needs to be set to com.android.application type module
|
||||
targetProjectPath = ":${projects.app.name}"
|
||||
// Run tests in this module
|
||||
experimentalProperties["android.experimental.self-instrumenting"] = true
|
||||
|
||||
defaultConfig {
|
||||
if (isOrchestratorEnabled) {
|
||||
|
@ -20,6 +24,17 @@ android {
|
|||
testInstrumentationRunner = "co.electriccoin.zcash.test.ZcashUiTestRunner"
|
||||
}
|
||||
|
||||
// Define the same flavors as in app module
|
||||
flavorDimensions.add("network")
|
||||
productFlavors {
|
||||
create("zcashtestnet") {
|
||||
dimension = "network"
|
||||
}
|
||||
create("zcashmainnet") {
|
||||
dimension = "network"
|
||||
}
|
||||
}
|
||||
|
||||
if (isOrchestratorEnabled) {
|
||||
testOptions {
|
||||
execution = "ANDROIDX_TEST_ORCHESTRATOR"
|
||||
|
@ -36,18 +51,18 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
androidTestImplementation(projects.uiLib)
|
||||
androidTestImplementation(projects.uiDesignLib)
|
||||
androidTestImplementation(projects.testLib)
|
||||
androidTestImplementation(projects.spackleAndroidLib)
|
||||
implementation(projects.uiLib)
|
||||
implementation(projects.uiDesignLib)
|
||||
implementation(projects.testLib)
|
||||
implementation(projects.spackleAndroidLib)
|
||||
|
||||
androidTestImplementation(libs.bundles.androidx.test)
|
||||
androidTestImplementation(libs.bundles.androidx.compose.core)
|
||||
androidTestImplementation(libs.bundles.play.core)
|
||||
implementation(libs.bundles.androidx.test)
|
||||
implementation(libs.bundles.androidx.compose.core)
|
||||
implementation(libs.bundles.play.core)
|
||||
|
||||
androidTestImplementation(libs.androidx.compose.test.junit)
|
||||
androidTestImplementation(libs.androidx.navigation.compose)
|
||||
androidTestImplementation(libs.androidx.uiAutomator)
|
||||
implementation(libs.androidx.compose.test.junit)
|
||||
implementation(libs.androidx.navigation.compose)
|
||||
implementation(libs.androidx.uiAutomator)
|
||||
|
||||
if (isOrchestratorEnabled) {
|
||||
androidTestUtil(libs.androidx.test.orchestrator) {
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application
|
||||
android:label="zcash-ui-integration-test">
|
|
@ -11,9 +11,11 @@ import androidx.test.uiautomator.UiSelector
|
|||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
fun getStringResource(@StringRes resId: Int) = ApplicationProvider.getApplicationContext<Context>().getString(resId)
|
||||
fun getStringResource(@StringRes resId: Int) =
|
||||
ApplicationProvider.getApplicationContext<Context>().getString(resId)
|
||||
|
||||
fun getStringResourceWithArgs(@StringRes resId: Int, vararg formatArgs: String) = ApplicationProvider.getApplicationContext<Context>().getString(resId, *formatArgs)
|
||||
fun getStringResourceWithArgs(@StringRes resId: Int, vararg formatArgs: String) =
|
||||
ApplicationProvider.getApplicationContext<Context>().getString(resId, *formatArgs)
|
||||
|
||||
// We're using indexes to find the right button, as it seems to be the best available way to test a click
|
||||
// action on a permission button. These indexes remain the same for LTR as well as RTL layout direction.
|
Loading…
Reference in New Issue