Enhancing iOS App Automation by Implementing Push Notification Automation at Halodoc

At Halodoc, ensuring our mobile applications function smoothly is essential for delivering a top-tier user experience. Push notifications are a critical feature for keeping both doctors and patients informed and engaged. For instance, doctors are notified when they receive requests from patients, and patients are updated when there is a follow-up from their doctor. Given the importance of these notifications, rigorous testing is crucial to avoid any potential oversights that could impact user experience. For a deeper exploration of the challenges we encountered and the benefits of automating push notifications, please refer to our blog.

In this blog, we discuss how we utilise XCUITest to automate the testing of push notifications in our iOS app. We'll cover our approach to setting up automated tests, the specific challenges we encountered, and the solutions we implemented to ensure timely, accurate, and reliable notifications.

Technologies and Tools for Push Notification Automation

We leverage XCUITest, a powerful framework built by Apple for testing iOS applications. Using XCUITest, we automate push notification testing by simulating various user scenarios, ensuring notifications are delivered and displayed accurately under different conditions. Our setup also supports testing notifications in multiple languages, such as English and Bahasa, ensuring they are displayed correctly for users across diverse regions.

To learn more about XCUITest and our iOS testing framework, please refer to our blog on iOS XCUITest with Cucumberish.

Key Steps to Manually Test Push Notifications

Before automating the process, testing push notifications at Halodoc involved several detailed manual steps to ensure notifications behaved as expected under different conditions. Here’s an overview of the manual testing process:

  1. Triggering Notifications:
    Notifications were manually triggered either through the app's user flow (e.g., booking a service) or by sending an API request to simulate real-world scenarios.
  2. Verifying Notification Content:
    Each notification was reviewed manually to ensure the displayed content, including text, icons, and action buttons, matched the expected values for the given test case.
  3. Interacting with Notifications:
    Testers manually tapped or swiped notifications to simulate user interactions. This involved verifying that the corresponding in-app behavior—such as navigating to the right screen or dismissing the notification—was functioning correctly.
  4. Tracking Outcomes:
    After interacting with the notification, testers manually checked the app’s response or reviewed log files to confirm that the expected behavior was triggered. This process was repeated across various scenarios to ensure consistency.

Testing Notifications Across Different App States

To ensure notifications functioned properly regardless of the app's state, we conducted these manual tests in several key scenarios:

  • App in Foreground: Verify that notifications display correctly without interrupting ongoing processes while the app is open.
  • App in Background: Switch the app to the background, trigger notifications, and confirm their appearance in the notification tray.
  • App Closed: With the app fully closed, check that notifications are delivered and that tapping them brings the app back to the foreground.
  • Device Locked: Lock the device and observe whether notifications appear on the lock screen. After unlocking, verify that notifications behave as expected.

While this manual approach was thorough, it was also time-consuming and repetitive. To enhance efficiency, we introduced automation for push notification testing, which allowed us to streamline and scale these steps across multiple app states and scenarios.

Step-by-Step Guide to Implementing Push Notification Automation

Automating push notifications on iOS requires a tailored approach, as certain manual actions like accessing the notification panel are restricted for security reasons. However, using Cucumber, Swift, and the XCUITest framework, we can interact with notifications as they appear directly on the device. Below is a step-by-step guide on how we automate push notifications in iOS:

Step 1: Initialise XCUIApplication:  To interact with system notifications, we need to initialise an instance of XCUIApplication using the bundle identifier of Springboard, which manages iOS’s home screen. This step allows us to access the notification banners directly through the Springboard app, which is crucial for automating system notifications.

Step 2: Trigger Push Notifications: To automate push notifications effectively, we can initiate them either through user actions in the app or by sending backend API requests. This approach allows us to test notifications in various scenarios.

For example, in the case of booking a lab test, the notification can be triggered by simulating the entire user flow where a user books a lab test through the app's UI. This mirrors how users interact with the app, triggering a push notification upon successful booking. Alternatively, the same notification can be triggered by directly interacting with the backend system. In this case, an API request is made to book or update the lab order, which will also trigger the push notification without the need to navigate through the app’s interface. By combining both UI-driven and backend-triggered flows, we ensure that push notifications are thoroughly tested for accuracy and reliability, whether they originate from user actions or backend events.

Step 3: Wait for the Notification and Locate the Element: Since notifications can take a few moments to appear, it's essential to wait for them before interacting. We use a custom function like waitForElementToAppear to pause the test execution until the notification is visible.

Once the notification is triggered, we locate it on the screen using the .descendants method within the Springboard app. This method allows us to search for UI elements using various filters, such as element type, identifier, or custom predicates. Currently, we are using the .any method, which locates any element present in the Springboard at that moment. While .any helps us find and interact with notifications, it has limitations. This approach does not allow us to verify the specific content of the push notification, as it only taps on whatever element appears. This is a current constraint of our implementation, which has been explained in limitations section.

To improve this process, we plan to incorporate other filtering methods, such as .elementType, .matching(identifier:), or .matching(NSPredicate:). These methods would enable us to more precisely identify and verify the content of the notifications, addressing the current limitation and enhancing the robustness of our testing.

Step 4: Interact with the Notification: Once the notification appears, we verify that it exists using the exists property. If the notification is present, we simulate user interaction by tapping on it, which will trigger the associated app behaviour.

Step 5: Verify Push Notifications in different app states: In iOS, push notifications behave differently depending on the app's state—whether it is in the foreground, background, or terminated (killed). To ensure comprehensive testing, we verify that push notifications function correctly in all scenarios using the example of booking a lab order:

  • App in Foreground: When the app is active and running, notifications are handled directly within the app’s UI. For example, if a user books a lab order while the app is in the foreground, the push notification will be handled internally. Upon tapping the notification, the user should be navigated to the Order Details page, regardless of where they are within the app.
  • App in Background: If the app is running in the background, notifications appear as banners in the iOS Springboard. Tapping the notification should bring the app back to the foreground and navigate the user to the Order Details page for the booked lab order, ensuring the user can easily access the information they need.
  • App in Terminated (Killed) State: When the app is completely closed, notifications also appear in the iOS Springboard. Tapping the notification should relaunch the app and navigate the user to the Order Details page for the booked lab order, ensuring that users are guided directly to the relevant screen even if the app was not running.

By verifying push notifications in these different app states, we ensure that users experience a seamless flow from the notification to the desired screen, regardless of the app's state.

Step 5: Ensure Correct Navigation to the Target Screen: Verifying that tapping on a Push Notification navigates to the correct page within the app is essential for validating the user experience and the notification flow. For example, after successfully booking a lab order, we ensure that the push notification directs the user to the Order Details page with "Booked" status , where they can view the specifics of their recent booking. This confirmation ensures that notifications consistently lead users to the appropriate screens.

Step 6: Clean Up: Before running the next test, it’s important to clean up the environment by closing the app and resetting the device state. This ensures that previous test results don’t affect the current session.

Limitations

Implementing automated push notification testing on iOS presents several key challenges:

  • Timing Challenges in Handling Notifications : iOS push notifications are transient and disappear quickly while the app is in the foreground. Automation scripts must be capable of detecting and interacting with these notifications within this short display window. Delays in detection or interaction may cause tests to fail or produce unreliable results. Handling this brief visibility window requires precise timing and synchronization mechanisms in the test scripts. Implementing a robust polling mechanism to continuously check for notifications can help ensure timely interaction with them as soon as they appear.

Conclusion

Automating push notification testing with XCUITest has significantly improved our iOS testing process by addressing key challenges and enhancing accuracy. By automating notification handling, we've streamlined the validation of dynamic content and multilingual support, ensuring a seamless user experience. For a detailed discussion of the overall benefits and our Android implementation, please refer to our  Parent Blog.

References

Enhancing App Automation by Implementing Push Notification Automation at Halodoc.
At Halodoc, ensuring efficient and thorough testing of our mobile applicationsis paramount. Push notifications are a critical feature we test extensively, asthey play a vital role in maintaining user engagement and ensuring timelycommunication. Notifications inform doctors when they receive pat…
Enhancing Android App Automation by Implementing Push Notification Automation at Halodoc.
At Halodoc, ensuring efficient and thorough testing of our mobile applicationsis paramount. Push notifications are a critical feature we test extensively, asthey play a vital role in maintaining user engagement and ensuring timelycommunication. Notifications inform doctors when they receive patie…
Notifications - Apple Developer
Find the essential documentation and sample code for using local and push notifications in your iOS and Mac apps.
What you Need to know About Automating Push Notification Testing
Push notifications are used to integrate real-time messaging to your apps. It keeps you in touch with users and makes it easy for your users to communicate. These are easy to love and hate. Consider…

Join Us

Scalability, reliability, and maintainability are the three pillars that govern what we build at Halodoc Tech. We are actively looking for engineers at all levels and if solving hard problems with challenging requirements is your forte, please reach out to us with your resumé at careers.india@halodoc.com.

About Halodoc

Halodoc is the number one all-around healthcare application in Indonesia. Our mission is to simplify and bring quality healthcare across Indonesia, from Sabang to Merauke. We connect 20,000+ doctors with patients in need through our Tele-consultation service. We partner with 3500+ pharmacies in 100+ cities to bring medicine to your doorstep. We've also partnered with Indonesia's largest lab provider to provide lab home services, and to top it off we have recently launched a premium appointment service that partners with 500+ hospitals that allow patients to book a doctor appointment inside our application. We are extremely fortunate to be trusted by our investors, such as the Bill & Melinda Gates Foundation, Singtel, UOB Ventures, Allianz, GoJek, Astra, Temasek, and many more. We recently closed our Series D round and in total have raised around USD$100+ million for our mission. Our team works tirelessly to make sure that we create the best healthcare solution personalised for all of our patient's needs, and are continuously on a path to simplify healthcare for Indonesia.