KasperskyLab / Kaspresso

Android UI test framework
https://kasperskylab.github.io/Kaspresso/
Apache License 2.0
1.81k stars 153 forks source link

Kaspresso with LeakAssertions #387

Closed PaladiRka closed 2 years ago

PaladiRka commented 2 years ago

I tried combine Kaspresso with LeakAssertions. And some UI test failed by Kaspresso LanguageImpl.cachedActivity (Log below).

Application memory leaks were detected:
====================================
HEAP ANALYSIS RESULT
====================================
2 APPLICATION LEAKS

References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.

382528 bytes retained by leaking objects
Signature: f8cb42f36daef658bb5683aa2c527e197f776713
┬───
│ GC Root: Input or output parameters in native code
│
├─ MyTest instance
│    Leaking: UNKNOWN
│    Retaining 389,4 kB in 5372 objects
│    ↓ BaseTestCase.device
│                   ~~~~~~
├─ com.kaspersky.kaspresso.device.Device instance
│    Leaking: UNKNOWN
│    Retaining 109 B in 3 objects
│    context instance of android.app.ContextImpl
│    targetContext instance of android.app.ContextImpl
│    ↓ Device.language
│             ~~~~~~~~
├─ com.kaspersky.kaspresso.device.languages.LanguageImpl instance
│    Leaking: UNKNOWN
│    Retaining 382,6 kB in 5131 objects
│    cachedActivity instance of MyActivity with mDestroyed = true
│    context instance of android.app.ContextImpl
│    ↓ LanguageImpl.cachedActivity
│                   ~~~~~~~~~~~~~~
╰→ MyActivity instance
​     Leaking: YES (ObjectWatcher was watching this because MyActivity received Activity#onDestroy() callback and Activity#mDestroyed is true)
​     Retaining 382,5 kB in 5129 objects
​     key = 065172ba-73f3-4afc-bbb2-21f155580fee
​     watchDurationMillis = 11770
​     retainedDurationMillis = 6768
​     mApplication instance of MyApp
​     mBase instance of androidx.appcompat.view.ContextThemeWrapper

And I suggest fix. LanguageImpl subscribe on ActivityLifecycle and cached activity when it created but don't clear activity when it destroyed.

https://github.com/KasperskyLab/Kaspresso/blob/c3d6d547ec57b9db8c53eafdf75e1142defb00de/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt#L22-L26

        if ((stage == Stage.DESTROYED) and (activity == cachedActivity)) {
            cachedActivity = null
        }
AzamatCherchesov commented 2 years ago

@PaladiRka thanks for opening this issue and your PR. Fix was included in release 1.4.2