Improved test cases and fixed memory leak in application.

* Previously our test cases were launching the `KiwixMainActivity` twice (firstly it sets the values in preference and then relaunch the activity) before running the test case which was the cause of slow testing and sometimes it caused to memory leak in some api levels so we have refactored our test cases to launch `KiwixMainTest` once per test case.
* `IntroFragmentTest` is failing on api level 24 due to a memory leak because after clicking on getStarted button is going to the LocalLibrary page but somehow `onStart` and `onStop` methods are calling of the `CoreReaderFragment` which stablish the `serviceConnection` but it was happening very quickly so before attaching the binder to `readAloudService` unbindService method called but at this point service was not created but creating was in progress so after going to library screen it allocate memory to `readAloudService` but `ReaderFragment` is no more visible to the user that's why memory leak happened. We have fixed it by unbinding the service in `onDestroyView` method.
This commit is contained in:
MohitMali 2023-08-29 16:56:43 +05:30 committed by Kelson
parent fff9196337
commit 1281c0c795
13 changed files with 67 additions and 13 deletions

View File

@ -21,7 +21,7 @@ package org.kiwix.kiwixmobile
import android.Manifest.permission
import android.content.Context
import android.os.Build
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.rule.GrantPermissionRule
@ -33,8 +33,7 @@ import org.kiwix.kiwixmobile.main.KiwixMainActivity
@RunWith(AndroidJUnit4::class)
abstract class BaseActivityTest {
@get:Rule
open var activityScenarioRule = ActivityScenarioRule(KiwixMainActivity::class.java)
open lateinit var activityScenario: ActivityScenario<KiwixMainActivity>
private val permissions = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
arrayOf(

View File

@ -19,6 +19,7 @@ package org.kiwix.kiwixmobile.download
import android.util.Log
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.IdlingPolicies
@ -73,11 +74,13 @@ class DownloadTest : BaseActivityTest() {
putBoolean(SharedPreferenceUtil.IS_PLAY_STORE_BUILD, true)
putBoolean(SharedPreferenceUtil.PREF_IS_TEST, true)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun downloadTest() {
ActivityScenario.launch(KiwixMainActivity::class.java)
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
try {
downloadRobot {

View File

@ -17,6 +17,8 @@
*/
package org.kiwix.kiwixmobile.help
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import leakcanary.LeakAssertions
@ -25,6 +27,7 @@ import org.junit.Rule
import org.junit.Test
import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.testutils.RetryRule
import org.kiwix.kiwixmobile.testutils.TestUtils.closeSystemDialogs
import org.kiwix.kiwixmobile.testutils.TestUtils.isSystemUINotRespondingDialogVisible
@ -39,6 +42,9 @@ class HelpFragmentTest : BaseActivityTest() {
}
waitForIdle()
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Rule
@ -47,7 +53,7 @@ class HelpFragmentTest : BaseActivityTest() {
@Test
fun verifyHelpActivity() {
activityScenarioRule.scenario.onActivity {
activityScenario.onActivity {
it.navigate(R.id.helpFragment)
}
help {

View File

@ -19,6 +19,7 @@
package org.kiwix.kiwixmobile.initial.download
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
@ -63,11 +64,13 @@ class InitialDownloadTest : BaseActivityTest() {
putBoolean(SharedPreferenceUtil.IS_PLAY_STORE_BUILD, true)
putBoolean(SharedPreferenceUtil.PREF_IS_TEST, true)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun initialDownloadTest() {
ActivityScenario.launch(KiwixMainActivity::class.java)
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS_FOR_SEARCH_TEST.toLong())
initialDownload {
clickLibraryOnBottomNav()

View File

@ -18,7 +18,9 @@
package org.kiwix.kiwixmobile.intro
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import leakcanary.LeakAssertions
@ -28,6 +30,7 @@ import org.junit.Test
import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.testutils.RetryRule
import org.kiwix.kiwixmobile.testutils.TestUtils.closeSystemDialogs
import org.kiwix.kiwixmobile.testutils.TestUtils.isSystemUINotRespondingDialogVisible
@ -40,7 +43,7 @@ class IntroFragmentTest : BaseActivityTest() {
@Test
fun viewIsSwipeableAndNavigatesToMain() {
activityScenarioRule.scenario.onActivity {
activityScenario.onActivity {
it.navigate(R.id.introFragment)
}
intro(IntroRobot::swipeLeft) clickGetStarted {}
@ -58,5 +61,8 @@ class IntroFragmentTest : BaseActivityTest() {
PreferenceManager.getDefaultSharedPreferences(context).edit {
putBoolean(SharedPreferenceUtil.PREF_SHOW_INTRO, true)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
}

View File

@ -18,6 +18,7 @@
package org.kiwix.kiwixmobile.main
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.platform.app.InstrumentationRegistry
@ -59,11 +60,13 @@ class TopLevelDestinationTest : BaseActivityTest() {
putBoolean(SharedPreferenceUtil.PREF_IS_TEST, true)
putBoolean(SharedPreferenceUtil.PREF_EXTERNAL_LINK_POPUP, true)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun testTopLevelDestination() {
ActivityScenario.launch(KiwixMainActivity::class.java)
topLevel {
clickReaderOnBottomNav {
}

View File

@ -19,7 +19,9 @@
package org.kiwix.kiwixmobile.mimetype
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import org.junit.Assert
@ -30,6 +32,7 @@ import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.core.NightModeConfig
import org.kiwix.kiwixmobile.core.reader.ZimFileReader
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.testutils.TestUtils.closeSystemDialogs
import org.kiwix.kiwixmobile.testutils.TestUtils.isSystemUINotRespondingDialogVisible
import java.io.File
@ -50,6 +53,9 @@ class MimeTypeTest : BaseActivityTest() {
putBoolean(SharedPreferenceUtil.PREF_SHOW_INTRO, false)
putBoolean(SharedPreferenceUtil.PREF_WIFI_ONLY, false)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test

View File

@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.nav.destination.library
import androidx.core.content.ContextCompat
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.platform.app.InstrumentationRegistry
@ -65,11 +66,14 @@ class LocalLibraryTest : BaseActivityTest() {
// manage external storage permission dialog on android 11 and above
putBoolean(SharedPreferenceUtil.PREF_MANAGE_EXTERNAL_FILES, false)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun testLocalLibrary() {
ActivityScenario.launch(KiwixMainActivity::class.java).onActivity {
activityScenario.onActivity {
it.navigate(R.id.libraryFragment)
}
library {

View File

@ -18,6 +18,8 @@
package org.kiwix.kiwixmobile.note
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import leakcanary.LeakAssertions
@ -26,6 +28,7 @@ import org.junit.Rule
import org.junit.Test
import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.testutils.RetryRule
import org.kiwix.kiwixmobile.testutils.TestUtils.closeSystemDialogs
import org.kiwix.kiwixmobile.testutils.TestUtils.isSystemUINotRespondingDialogVisible
@ -44,11 +47,14 @@ class NoteFragmentTest : BaseActivityTest() {
}
waitForIdle()
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun verifyNoteFragment() {
activityScenarioRule.scenario.onActivity {
activityScenario.onActivity {
it.navigate(R.id.notesFragment)
}
note {

View File

@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.page.history
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
@ -63,11 +64,14 @@ class NavigationHistoryTest : BaseActivityTest() {
putBoolean(SharedPreferenceUtil.PREF_WIFI_ONLY, false)
putBoolean(SharedPreferenceUtil.PREF_IS_TEST, true)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun navigationHistoryDialogTest() {
ActivityScenario.launch(KiwixMainActivity::class.java).onActivity {
activityScenario.onActivity {
kiwixMainActivity = it
kiwixMainActivity.navigate(R.id.libraryFragment)
}

View File

@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.reader
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
@ -62,11 +63,14 @@ class KiwixReaderFragmentTest : BaseActivityTest() {
putBoolean(SharedPreferenceUtil.PREF_WIFI_ONLY, false)
putBoolean(SharedPreferenceUtil.PREF_IS_TEST, true)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun testTabClosedDialog() {
ActivityScenario.launch(KiwixMainActivity::class.java).onActivity {
activityScenario.onActivity {
kiwixMainActivity = it
kiwixMainActivity.navigate(R.id.libraryFragment)
}

View File

@ -19,6 +19,7 @@ package org.kiwix.kiwixmobile.search
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
@ -62,11 +63,14 @@ class SearchFragmentTest : BaseActivityTest() {
putBoolean(SharedPreferenceUtil.PREF_WIFI_ONLY, false)
putBoolean(SharedPreferenceUtil.PREF_IS_TEST, true)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun searchFragmentSimple() {
ActivityScenario.launch(KiwixMainActivity::class.java).onActivity {
activityScenario.onActivity {
kiwixMainActivity = it
kiwixMainActivity.navigate(R.id.libraryFragment)
}

View File

@ -1041,6 +1041,12 @@ abstract class CoreReaderFragment :
tts = null
}
tempWebViewForUndo = null
// to fix IntroFragmentTest see https://github.com/kiwix/kiwix-android/pull/3217
try {
requireActivity().unbindService(serviceConnection)
} catch (ignore: IllegalArgumentException) {
// to handle if service is already unbounded
}
readAloudService?.registerCallBack(null)
readAloudService = null
storagePermissionForNotesLauncher?.unregister()