Updated on 2026-08-14
This commit is contained in:
parent
2a835ce3c9
commit
0c56df0075
16 changed files with 306 additions and 58 deletions
|
|
@ -1,7 +1,8 @@
|
|||
package com.tangem.common
|
||||
|
||||
import android.Manifest
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.compose.ui.test.junit4.createEmptyComposeRule
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.espresso.intent.Intents
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import com.kaspersky.components.alluresupport.interceptors.step.ScreenshotStepInterceptor
|
||||
|
|
@ -10,8 +11,8 @@ import com.kaspersky.components.composesupport.config.addComposeSupport
|
|||
import com.kaspersky.kaspresso.kaspresso.Kaspresso
|
||||
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
|
||||
import com.tangem.common.allure.FailedStepScreenshotInterceptor
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.common.rules.ApiEnvironmentRule
|
||||
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
||||
import com.tangem.tap.MainActivity
|
||||
import dagger.hilt.android.testing.HiltAndroidRule
|
||||
import org.junit.Rule
|
||||
|
|
@ -35,17 +36,20 @@ abstract class BaseTestCase : TestCase(
|
|||
) {
|
||||
|
||||
@Inject
|
||||
lateinit var tangemSdkManager: TangemSdkManager
|
||||
|
||||
@Inject
|
||||
lateinit var appPreferencesStore: AppPreferencesStore
|
||||
lateinit var apiConfigsManager: ApiConfigsManager
|
||||
|
||||
private val hiltRule = HiltAndroidRule(this)
|
||||
private val permissionRule = GrantPermissionRule.grant(
|
||||
private val apiEnvironmentRule = ApiEnvironmentRule()
|
||||
private val permissionRule = GrantPermissionRule.grant(
|
||||
Manifest.permission.POST_NOTIFICATIONS,
|
||||
Manifest.permission.CAMERA,
|
||||
)
|
||||
val composeTestRule = createAndroidComposeRule<MainActivity>()
|
||||
|
||||
/**
|
||||
* It is important to use `ComposeRule` without specifying an activity to ensure that the initialization order of
|
||||
* all test rules is fully controlled.
|
||||
*/
|
||||
val composeTestRule = createEmptyComposeRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
|
|
@ -53,18 +57,26 @@ abstract class BaseTestCase : TestCase(
|
|||
.outerRule(hiltRule)
|
||||
.around(ApplicationInjectionExecutionRule())
|
||||
.around(permissionRule)
|
||||
.around(apiEnvironmentRule)
|
||||
.around(composeTestRule)
|
||||
|
||||
/**
|
||||
* Initialization order is important:
|
||||
* – DI dependencies must be injected first,
|
||||
* – then the API environment should be set up,
|
||||
* – and only after that the activity should be launched.
|
||||
*/
|
||||
protected fun setupHooks(
|
||||
additionalBeforeSection: () -> Unit = {},
|
||||
additionalAfterSection: () -> Unit = {},
|
||||
) = before {
|
||||
hiltRule.inject()
|
||||
apiEnvironmentRule.setup(apiConfigsManager)
|
||||
ActivityScenario.launch(MainActivity::class.java)
|
||||
Intents.init()
|
||||
additionalBeforeSection()
|
||||
}.after {
|
||||
additionalAfterSection()
|
||||
Intents.release()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.common.annotations
|
||||
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||
|
||||
/**
|
||||
* Annotation to specify the API environment for a class or function.
|
||||
*
|
||||
* @property environment the API environment to be used (defaults to [ApiEnvironment.MOCK])
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class ApiEnv(
|
||||
val environment: ApiEnvironment = ApiEnvironment.MOCK,
|
||||
)
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package com.tangem.common.rules
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.tangem.common.annotations.ApiEnv
|
||||
import com.tangem.datasource.api.common.config.ApiEnvironment
|
||||
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
||||
import com.tangem.datasource.api.common.config.managers.MutableApiConfigsManager
|
||||
import com.tangem.wallet.test.BuildConfig
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* A JUnit rule that sets up the API environment for tests based on annotations or instrumentation arguments.
|
||||
*
|
||||
* This rule allows tests to specify which API environment to use either through an annotation on the test method/class
|
||||
* or via an instrumentation argument.
|
||||
*
|
||||
* This rule only finds and stores the required API environment. The actual environment setup is performed
|
||||
* by calling the [setup] method with an appropriate [ApiConfigsManager] instance.
|
||||
*/
|
||||
class ApiEnvironmentRule : TestRule {
|
||||
|
||||
private var targetEnvironment: ApiEnvironment? = null
|
||||
|
||||
/**
|
||||
* Sets up the API environment based on the provided [ApiConfigsManager].
|
||||
* This method is typically called in the test setup phase to ensure the correct API environment is configured.
|
||||
*
|
||||
* @param apiConfigsManager the manager responsible for API configurations
|
||||
*/
|
||||
fun setup(apiConfigsManager: ApiConfigsManager) {
|
||||
val mutableManager = requireNotNull(apiConfigsManager as? MutableApiConfigsManager) {
|
||||
"MutableApiConfigsManager isn't available in build type ${BuildConfig.BUILD_TYPE}."
|
||||
}
|
||||
|
||||
mutableManager.setupEnvironment()
|
||||
}
|
||||
|
||||
override fun apply(base: Statement, description: Description): Statement {
|
||||
return object : Statement() {
|
||||
override fun evaluate() {
|
||||
targetEnvironment = determineEnvironment(description)
|
||||
|
||||
base.evaluate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun determineEnvironment(description: Description): ApiEnvironment {
|
||||
val instrumentationArgs = InstrumentationRegistry.getArguments()
|
||||
val envArg = instrumentationArgs.getString(ENV_ARGUMENT)
|
||||
|
||||
if (!envArg.isNullOrEmpty()) return ApiEnvironment.valueOf(envArg.uppercase())
|
||||
|
||||
val methodAnnotation = description.getAnnotation(ApiEnv::class.java)
|
||||
if (methodAnnotation != null) return methodAnnotation.environment
|
||||
|
||||
val classAnnotation = description.testClass.getAnnotation(ApiEnv::class.java)
|
||||
if (classAnnotation != null) return classAnnotation.environment
|
||||
|
||||
return ApiEnvironment.MOCK
|
||||
}
|
||||
|
||||
private fun MutableApiConfigsManager.setupEnvironment() {
|
||||
val environment = requireNotNull(targetEnvironment) { "Target environment is null" }
|
||||
|
||||
runBlocking { changeEnvironment(environment) }
|
||||
|
||||
Timber.i("API environment set to: ${environment.name}")
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val ENV_ARGUMENT = "testEnvironment"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue