chore: Improve Unit Test and Instrumentation Test Coverage#514
Open
adeekshith wants to merge 11 commits intomainfrom
Open
chore: Improve Unit Test and Instrumentation Test Coverage#514adeekshith wants to merge 11 commits intomainfrom
adeekshith wants to merge 11 commits intomainfrom
Conversation
- Add Robolectric unit tests for PreferencesManager (80 tests), CustomRepliesData (17 tests), NotificationUtils (12 tests), and Constants (20 tests) - Add instrumentation tests for MainActivity and PreferencesManager on real device - Add mockito-kotlin dependency for Kotlin-idiomatic mocking - Add @VisibleForTesting resetInstance() methods to PreferencesManager and CustomRepliesData for test isolation - Guard EncryptedSharedPreferences init against hardware Keystore unavailability in test environments by catching Error in addition to checked exceptions - Guard string resource lookups in init() with try-catch to handle Robolectric resource resolution limitations; pre-initialize keys with literal fallback values
Tests added (202 total, 0 failures): - NetworkModelsTest: 35 tests covering all OpenAI/Atomatic request+response POJOs including AtomaticAIErrorResponse.isAuthError() branch logic - MessageLogTest: 17 tests covering Room entity constructor, getters/setters, UUID generation - GithubReleaseNotesTest: 9 tests covering Parcelable serialization via writeToParcel/CREATOR - NotificationUtilsTest: expanded from 12 to 21 tests, adding extractWearNotification scenarios (no actions, single reply action, reply-action selection priority, tag capture) and group title message-count trimming branch Build config: - Add JaCoCo plugin + jacocoUnitTestReport task for coverage reporting - Enable enableUnitTestCoverage in debug build type Documentation: - Add CLAUDE.md with build instructions, test run commands, test architecture overview, common issues (JAVA_HOME, Robolectric resource errors, Keystore unavailability), and note on JaCoCo/Robolectric incompatibility with offline instrumentation
New tests (+56 unit tests, 211 → 267 total): PreferencesManagerTest (+38): - Show notification pref (new-install init, get/set) - GitHub release notes ID, last purged time - Play store rating status and timestamp - Foreground service notification pref - Reply-to names and custom reply names (StringSet) - Generic getString / saveString - Subscription status last checked, product name - Deprecated isOpenAIRepliesEnabled / setEnableOpenAIReplies - Enabled apps: saveEnabledApps(String), saveEnabledApps(App), getEnabledApps, isAppEnabled(String), isAppEnabled(App) - isFirstInstall static method CustomRepliesDataTest (+14): - getTextToSendOrElse: non-AI, automatic AI, BYOK, attribution on/off, AI result vs custom reply - set(Editable): null, valid, empty - isValidCustomReply(Editable): null, valid, empty, too-long, at-max-length NotificationUtilsTest (+4): - extractWearNotification picks from WearableExtender - showAccessRevokedNotification: smoke test, channel creation, notification posted (via ShadowNotificationManager) Production fix: - CustomRepliesData.getTextToSendOrElse() now wraps getString() calls in try-catch with hardcoded fallbacks, consistent with the init() pattern used throughout the codebase, enabling unit testing and improving robustness.
MainActivityTest: remove duplicate lifecycle test; add 8 new Espresso checks for ai_reply_text, btn_edit, bottom_nav, all four filter rows, and a test verifying the auto-reply switch state matches PreferencesManager. PreferencesManagerInstrumentedTest: clear SharedPreferences in setUp and tearDown so tests are fully isolated and order-independent; fix serviceEnabledDefaultsToFalseOnFreshInstance to be reliable from a known-clean state; fix setAndGetServiceEnabled to assert from a known starting point rather than toggling an unknown value.
Add 9 new test files covering previously untested classes: - AppTest, ContactHolderTest, AppPackageTest (plain JUnit) - OpenAIHelperTest, NotificationHelperTest, DbUtilsTest, ContactsHelperTest, AutoStartHelperTest (Robolectric) Add edge cases to 4 existing test files: - PreferencesManagerTest: boundary timestamps, empty sets, concurrent reset - NotificationUtilsTest: emoji/RTL titles, null group title NPE (documents bug), future timestamps, actions without RemoteInput - CustomRepliesDataTest: fresh instance get(), max-length reply - AppUtilsTest: singleton identity, reset, empty package name Add resetInstance() to NotificationHelper for test isolation, consistent with PreferencesManager/AppUtils/CustomRepliesData pattern.
Add 5 new instrumentation test files: - SettingsActivityTest: launch, toolbar, fragment container, up button - AboutActivityTest: launch, version display, privacy/developer links - DonationActivityTest: launch, root layout, fragment container - CustomReplyEditorActivityTest: reply method cards, save button, toolbar - CustomRepliesDataInstrumentedTest: real-device SharedPreferences persistence Expand MainActivityTest with bottom nav items, filter description visibility/content checks, and proper state isolation in setUp/tearDown.
… tests New test files: - SubscriptionInfoActivityTest: launch with all modes (MANAGE/UPGRADE), toolbar, state views (loading/active/inactive), subscription UI elements - OtherAiConfigurationActivityTest: launch, form fields (provider dropdown, API key, model selector, system prompt), save button, base URL visibility Fixes for GooglePlay flavor compatibility: - MainActivityTest: set guest mode before launch to bypass login redirect - ExampleInstrumentedTest: accept both flavor package names All 112 instrumentation tests pass on both Default and GooglePlay flavors.
- Upgrade JDK from 17 to 21 to match project requirements - Replace generic ./gradlew test with explicit flavor targets (testDefaultDebugUnitTest + testGooglePlayDebugUnitTest) - Add instrumentation test job running on API 28 emulator - Add JaCoCo coverage report generation and artifact upload - Add Gradle caching via gradle/actions/setup-gradle - Fix deprecated set-output syntax in APK upload steps
On Android 13+ (API 33+), MainFragment requests POST_NOTIFICATIONS in onCreateView, which shows a system dialog that blocks Espresso. Use UiAutomation.grantRuntimePermission() in setUp to prevent this.
- NotificationHelperTest: check all notifications for WhatsApp title prefix instead of assuming first notification is the individual one (ordering differs between local and CI Robolectric environments) - DonationActivityTest: remove recreation test that crashes due to DonationFragment Retrofit callback calling requireContext() after fragment detaches, which kills the test process
The save button is below the fold on CI emulator (API 28) and scrollTo() is unreliable inside CoordinatorLayout. Use findViewById to verify the button exists in the layout instead.
There was a problem hiding this comment.
Pull request overview
This PR focuses on increasing test coverage across core model/utility logic (unit + Robolectric) and key screens (instrumentation), while adding JaCoCo reporting and expanding CI to build/test variants and publish artifacts.
Changes:
- Added extensive new unit/Robolectric tests for network models, preferences, notifications, helpers, and data models.
- Added multiple new Android instrumentation tests for major Activities and improved flavor-agnostic checks.
- Enabled JaCoCo + unit-test coverage reporting and updated GitHub Actions workflow to build, test, run emulator tests, and upload artifacts/reports.
Reviewed changes
Copilot reviewed 33 out of 33 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| gradle/libs.versions.toml | Adds mockito-kotlin version + library alias for Kotlin-friendly mocking. |
| app/build.gradle.kts | Enables debug unit test coverage, adds JaCoCo report task, adds mockito-kotlin test dep. |
| app/src/main/java/com/parishod/watomatic/model/utils/NotificationHelper.java | Adds resetInstance() to support test isolation. |
| app/src/main/java/com/parishod/watomatic/model/preferences/PreferencesManager.java | Adds safer defaults for preference keys, adds resetInstance(), and broadens exception handling for tests. |
| app/src/main/java/com/parishod/watomatic/model/CustomRepliesData.java | Adds resetInstance() and resource fallback strings for unit-test environments. |
| app/src/test/java/com/parishod/watomatic/network/model/NetworkModelsTest.kt | Adds JVM unit tests for OpenAI/Atomatic network model POJOs. |
| app/src/test/java/com/parishod/watomatic/model/utils/OpenAIHelperTest.kt | Adds Robolectric tests for OpenAI model caching behavior. |
| app/src/test/java/com/parishod/watomatic/model/utils/NotificationUtilsTest.kt | Adds Robolectric tests for notification parsing/extraction logic and edge cases. |
| app/src/test/java/com/parishod/watomatic/model/utils/NotificationHelperTest.kt | Adds Robolectric tests for notification posting/grouping behavior. |
| app/src/test/java/com/parishod/watomatic/model/utils/DbUtilsTest.kt | Adds Robolectric smoke/edge tests for DB utility behavior. |
| app/src/test/java/com/parishod/watomatic/model/utils/ContactsHelperTest.kt | Adds Robolectric tests around contacts permissions + custom contacts behavior. |
| app/src/test/java/com/parishod/watomatic/model/utils/AutoStartHelperTest.kt | Adds Robolectric smoke tests for autostart permission flow. |
| app/src/test/java/com/parishod/watomatic/model/utils/AppUtilsTest.java | Expands AppUtils tests (singleton + edge case). |
| app/src/test/java/com/parishod/watomatic/model/preferences/PreferencesManagerTest.kt | Adds large Robolectric test suite covering most preference behaviors and edge cases. |
| app/src/test/java/com/parishod/watomatic/model/logs/MessageLogTest.kt | Adds unit tests for MessageLog entity behavior and UUID generation. |
| app/src/test/java/com/parishod/watomatic/model/logs/AppPackageTest.kt | Adds unit tests for AppPackage entity. |
| app/src/test/java/com/parishod/watomatic/model/data/ContactHolderTest.kt | Adds unit tests for ContactHolder constructors/flags. |
| app/src/test/java/com/parishod/watomatic/model/GithubReleaseNotesTest.kt | Adds Robolectric parcelable tests for GithubReleaseNotes. |
| app/src/test/java/com/parishod/watomatic/model/CustomRepliesDataTest.kt | Adds Robolectric tests for validation, persistence, and AI/attribution behavior. |
| app/src/test/java/com/parishod/watomatic/model/ConstantsTest.kt | Adds unit tests for supported apps/providers/constants invariants. |
| app/src/test/java/com/parishod/watomatic/model/AppTest.kt | Adds unit tests for App data class equality/copy/toString. |
| app/src/androidTest/java/com/parishod/watomatic/SubscriptionInfoActivityTest.kt | Adds Espresso/ActivityScenario coverage for subscription UI wiring. |
| app/src/androidTest/java/com/parishod/watomatic/SettingsActivityTest.kt | Adds Espresso coverage for settings screen basics + recreation. |
| app/src/androidTest/java/com/parishod/watomatic/PreferencesManagerInstrumentedTest.kt | Adds device-level preferences/keystore behavior verification. |
| app/src/androidTest/java/com/parishod/watomatic/OtherAiConfigurationActivityTest.kt | Adds Espresso coverage for BYOK/other-provider configuration UI. |
| app/src/androidTest/java/com/parishod/watomatic/MainActivityTest.kt | Adds Espresso coverage for MainActivity UI presence + permission handling. |
| app/src/androidTest/java/com/parishod/watomatic/ExampleInstrumentedTest.java | Makes package-name assertion flavor-agnostic. |
| app/src/androidTest/java/com/parishod/watomatic/DonationActivityTest.kt | Adds Espresso coverage for donation screen basics. |
| app/src/androidTest/java/com/parishod/watomatic/CustomReplyEditorActivityTest.kt | Adds Espresso coverage for custom reply editor UI. |
| app/src/androidTest/java/com/parishod/watomatic/CustomRepliesDataInstrumentedTest.kt | Adds device-level persistence tests for CustomRepliesData. |
| app/src/androidTest/java/com/parishod/watomatic/AboutActivityTest.kt | Adds Espresso coverage for about screen UI + recreation. |
| CLAUDE.md | Adds a developer guide describing project structure, test commands, and coverage caveats. |
| .github/workflows/android.yml | Expands CI to build both flavors, run unit + instrumentation tests, and upload artifacts/reports. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
app/src/main/java/com/parishod/watomatic/model/utils/NotificationHelper.java
Show resolved
Hide resolved
app/src/test/java/com/parishod/watomatic/model/utils/NotificationUtilsTest.kt
Show resolved
Hide resolved
app/src/test/java/com/parishod/watomatic/model/utils/NotificationHelperTest.kt
Show resolved
Hide resolved
app/src/main/java/com/parishod/watomatic/model/preferences/PreferencesManager.java
Show resolved
Hide resolved
app/src/test/java/com/parishod/watomatic/model/utils/NotificationHelperTest.kt
Show resolved
Hide resolved
app/src/androidTest/java/com/parishod/watomatic/SubscriptionInfoActivityTest.kt
Show resolved
Hide resolved
app/src/androidTest/java/com/parishod/watomatic/OtherAiConfigurationActivityTest.kt
Show resolved
Hide resolved
49addf1 to
b2c7718
Compare
Owner
Author
|
Using JUnit assertions seems valid point based on its reasoning. Will plan to do it in another PR is it is relevant |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.