diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index b2bb1eb9c..785f615f7 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -61,7 +61,7 @@ jobs: - name: Run with Gradle uses: gradle/gradle-build-action with: - arguments: testProdDebugUnitTest + arguments: connectedProdDebugAndroidTest lint: runs-on: ubuntu-latest diff --git a/Habitica/build.gradle b/Habitica/build.gradle index fc35a4a2d..7b11e353f 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -91,7 +91,9 @@ dependencies { testImplementation "io.mockk:mockk-android:1.12.2" testImplementation 'io.kotest:kotest-assertions-core:5.0.3' testImplementation 'io.kotest:kotest-framework-datatest:4.6.2' - androidTestImplementation 'com.kaspersky.android-components:kaspresso:1.4.0' + androidTestImplementation ('com.kaspersky.android-components:kaspresso:1.4.0') { + exclude module: "protobuf-lite" + } androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation 'androidx.test:runner:1.4.0' androidTestImplementation 'androidx.test:rules:1.4.0' @@ -186,7 +188,7 @@ android { // Disable fabric build ID generation for debug builds ext.enableCrashlytics = false ext.alwaysUpdateBuildId = false - testCoverageEnabled = true + testCoverageEnabled = false resValue "string", "content_provider", "com.habitrpg.android.habitica.debug.fileprovider" resValue "string", "app_name", "Habitica Debug" } @@ -250,6 +252,9 @@ android { res.srcDirs = ['res'] assets.srcDirs = ['assets'] } + test { + java.srcDir("src/test/java") + } debugIAP { java.srcDirs = ['src/debug/java'] } release { java.srcDirs = ['src/release/java'] } } @@ -283,11 +288,21 @@ android { android.testOptions { unitTests.all { useJUnitPlatform() - unitTests.returnDefaultValues = true + testLogging { + events "passed", "skipped", "failed", "standardError" + outputs.upToDateWhen {false} + + afterSuite { desc, result -> + if (!desc.parent) { // will match the outermost suite + def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)" + def startItem = '| ', endItem = ' |' + def repeatLength = startItem.length() + output.length() + endItem.length() + println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength)) + } + } + } } unitTests.returnDefaultValues = true - - execution 'ANDROIDX_TEST_ORCHESTRATOR' } Properties props = new Properties() diff --git a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/FragmentTestCase.kt b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/FragmentTestCase.kt index 9784c3f2d..aaeacbcd2 100644 --- a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/FragmentTestCase.kt +++ b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/FragmentTestCase.kt @@ -7,16 +7,24 @@ import com.habitrpg.android.habitica.data.SocialRepository import com.habitrpg.android.habitica.data.TutorialRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.helpers.AppConfigManager +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.BaseObject import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.kaspersky.kaspresso.testcases.api.testcase.TestCase import io.github.kakaocup.kakao.screen.Screen +import io.mockk.called import io.mockk.clearAllMocks import io.mockk.every import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.slot import io.reactivex.rxjava3.core.BackpressureStrategy import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.subjects.PublishSubject +import io.realm.RealmObject +import org.junit.After import org.junit.Before abstract class FragmentTestCase, VB : ViewBinding, S : Screen> : TestCase() { @@ -29,6 +37,7 @@ abstract class FragmentTestCase, VB : ViewBinding, S : Scre val socialRepository: SocialRepository = mockk(relaxed = true) val tutorialRepository: TutorialRepository = mockk(relaxed = true) val appConfigManager: AppConfigManager = mockk(relaxed = true) + val userViewModel: MainUserViewModel = mockk(relaxed = true) abstract fun makeFragment() abstract val screen: S @@ -37,6 +46,9 @@ abstract class FragmentTestCase, VB : ViewBinding, S : Scre val userEvents: Flowable = userSubject.toFlowable(BackpressureStrategy.DROP) var user = User() + val errorSlot = slot() + val unmanagedSlot = slot() + @Before fun setUpFragment() { clearAllMocks() @@ -46,6 +58,11 @@ abstract class FragmentTestCase, VB : ViewBinding, S : Scre user.stats?.lvl = 20 user.stats?.points = 30 every { userRepository.getUser() } returns userEvents + mockkObject(RxErrorHandler.Companion) + every { RxErrorHandler.Companion.reportError(capture(errorSlot)) } answers { + throw errorSlot.captured + } + every { socialRepository.getUnmanagedCopy(capture(unmanagedSlot)) } answers { unmanagedSlot.captured } makeFragment() } } diff --git a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/PartyDetailFragmentTest.kt b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/PartyDetailFragmentTest.kt index 53507edbe..3d7045fb8 100644 --- a/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/PartyDetailFragmentTest.kt +++ b/Habitica/src/androidTest/java/com/habitrpg/android/habitica/ui/fragments/PartyDetailFragmentTest.kt @@ -41,6 +41,7 @@ class PartyDetailFragmentTest : FragmentTestCase() { } compositeSubscription.add( - userRepository.getUser().subscribe( + userRepository.getUser() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( { user -> canAllocatePoints = user.stats?.lvl ?: 0 >= 10 && user.stats?.points ?: 0 > 0 binding?.unlockAtLevel?.visibility = if (user.stats?.lvl ?: 0 < 10) View.VISIBLE else View.GONE