<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged appium</title>
<link>https://coderlegion.com/tag/appium</link>
<description>Powered by Question2Answer</description>
<item>
<title>Android/iOS Testing Perfected: 20 Appium Tricks You Need</title>
<link>https://coderlegion.com/1762/android-ios-testing-perfected-20-appium-tricks-you-need</link>
<description>&lt;p&gt;Appium is one of the(maybe number one) most popular open-source automation tool for testing mobile applications across iOS and Android platforms. Strong libraries, wide community and documentation support and years of experience across all the QA Enginners and most importantly Selenium-like syntax makes it top choice for Native Mobile App testing. If we know that, we should know how to make it perfect too.&lt;/p&gt;
&lt;h2 id=&quot;appium-best-practices-amp-tips&quot;&gt;Appium Best Practices &amp;amp; Tips&lt;/h2&gt;
&lt;h3 id=&quot;1-use-appium-inspector&quot;&gt;1. Use Appium Inspector&lt;/h3&gt;
&lt;p&gt;Appium Inspector helps in identifying element locators efficiently. It allows testers to inspect UI elements and retrieve attributes like &lt;code&gt;resource-id&lt;/code&gt;, &lt;code&gt;accessibility-id&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, and &lt;code&gt;class&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open Appium Inspector and connect to your running session.&lt;/li&gt;
&lt;li&gt;Click on elements to fetch their properties.&lt;/li&gt;
&lt;li&gt;Copy unique locators to use in your automation script, ensuring better test stability.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;2-find-exact-app-names-from-play-store&quot;&gt;2. Find Exact App Names from Play Store&lt;/h3&gt;
&lt;p&gt;To correctly launch an app using Appium, you need the exact package name and main activity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install the &quot;Package Name Viewer&quot; on an android test device.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use these details in your &lt;code&gt;capabilities&lt;/code&gt; while setting up Appium.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;3-download-trusted-apks&quot;&gt;3. Download trusted APKs&lt;/h3&gt;
&lt;p&gt;Some APK needs to be downloaded from external instead of play store. You should ALWAYS double check what you downloaded on your VD. It may not be seem harmful, but your work environment can contain sensitive information as usual.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;adb install &quot;C:\Users\YourUserName\Downloads\may-be-malware.apk&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you dont trust, open new virtual device and do not login your google account or elsewhere, then test the app there.&lt;/p&gt;
&lt;h3 id=&quot;4-advanced-adb-command-for-extracting-current-activity&quot;&gt;4. Advanced ADB Command for Extracting Current Activity&lt;/h3&gt;
&lt;p&gt;Instead of manually searching the activity name from &lt;code&gt;dumpsys window&lt;/code&gt;, use the following command to extract it precisely:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;adb shell dumpsys window | grep -oP '(?&amp;lt;=mCurrentFocus=Window{)[^}]+'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command extracts only the currently focused window, making it easier to grab the package and activity for use in Appium tests.&lt;/p&gt;
&lt;h3 id=&quot;5-disable-animations-via-adb&quot;&gt;5. Disable Animations via ADB&lt;/h3&gt;
&lt;p&gt;Animations can slow down tests and cause flakiness. Disable them using ADB commands.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This speeds up UI interactions during automation.&lt;/p&gt;
&lt;h3 id=&quot;6-page-object-model-pom-configurations&quot;&gt;6. Page Object Model (POM) Configurations&lt;/h3&gt;
&lt;p&gt;Using POM makes test scripts more structured and maintainable by separating UI elements and test logic. &lt;/p&gt;
&lt;p&gt;But you cannot use constructor as you used in Selenium before. &lt;code&gt;AppiumFieldDecorator&lt;/code&gt; is MUST due to its own lazy load handle nature. Its also good practice and sometimes we should go with &lt;code&gt;@AndroidFindBy&lt;/code&gt; annotation(iOS has also its own &lt;code&gt;@iOSFindBy&lt;/code&gt; annotation) instead of Seleniums &lt;code&gt;@FindBy&lt;/code&gt; annotation. Because it has just 8 locators and uiAutomator and accessibility not one of them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;public abstract class LandingPage {

    public LandingPage() {
        PageFactory.initElements(new AppiumFieldDecorator(getDriver()), this);
    }

    @AndroidFindBy(accessibility = &quot;Login Screen&quot;)
    public WebElement loginScreen;

    @AndroidFindBy(accessibility = &quot;Echo Box&quot;)
    public WebElement echoBoxScreen;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TL&amp;amp;DR; following this structure makes test cases more readable and reusable.&lt;/p&gt;
&lt;h3 id=&quot;7-prefer-accessibility-ids-and-resource-ids&quot;&gt;7. Prefer Accessibility IDs and Resource IDs&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Accessibility ID&lt;/code&gt; and &lt;code&gt;Resource ID&lt;/code&gt; are the most reliable locators compared to XPaths, making tests more stable and faster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;driver.findElement(MobileBy.AccessibilityId(&quot;SubmitButton&quot;)).click();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This avoids issues caused by UI structure changes.&lt;/p&gt;
&lt;h3 id=&quot;8-handle-flakiness-with-retries&quot;&gt;8. Handle Flakiness with Retries&lt;/h3&gt;
&lt;p&gt;Tests may fail due to temporary issues like slow network or animations. Implement retry logic to reduce false failures.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Test(retryAnalyzer = RetryAnalyzer.class)
public void testLogin() {
    // Test implementation
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This improves test reliability.&lt;/p&gt;
&lt;h3 id=&quot;9-explicit-waits&quot;&gt;9. Explicit Waits&lt;/h3&gt;
&lt;p&gt;Avoid using &lt;code&gt;Thread.sleep()&lt;/code&gt; as it introduces unnecessary delays. Instead, use explicit waits, which wait for an element until a specified condition is met.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(&quot;login_button&quot;)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures that your test does not proceed until the element is visible.&lt;/p&gt;
&lt;h3 id=&quot;10-parallel-test-execution&quot;&gt;10. Parallel Test Execution&lt;/h3&gt;
&lt;p&gt;Run tests on multiple devices simultaneously to speed up execution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;suite name=&quot;ParallelTests&quot; parallel=&quot;tests&quot; thread-count=&quot;2&quot;&amp;gt;
    &amp;lt;test name=&quot;AndroidTest1&quot;&amp;gt;
        &amp;lt;classes&amp;gt;
            &amp;lt;class name=&quot;tests.LoginTest&quot; /&amp;gt;
        &amp;lt;/classes&amp;gt;
    &amp;lt;/test&amp;gt;
&amp;lt;/suite&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This optimizes test execution time.&lt;/p&gt;
&lt;h3 id=&quot;11-use-uiautomator2&quot;&gt;11. Use UIAutomator2&lt;/h3&gt;
&lt;p&gt;UIAutomator2 is the recommended automation engine for Android as it provides better stability and speed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example (Java):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;capabilities.setCapability(&quot;automationName&quot;, &quot;UIAutomator2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures compatibility with modern Android versions.&lt;/p&gt;
&lt;h3 id=&quot;12-network-conditioning&quot;&gt;12. Network Conditioning&lt;/h3&gt;
&lt;p&gt;Simulate different network conditions like slow or no internet to test app behavior.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;adb shell am broadcast -a com.android.intent.action.SET_NETWORK_CONDITIONS --es condition slow
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This helps validate app performance under various network conditions.&lt;/p&gt;
&lt;h3 id=&quot;13-grant-permissions-via-adb&quot;&gt;13. Grant Permissions via ADB&lt;/h3&gt;
&lt;p&gt;Some apps require runtime permissions. Instead of manually accepting popups, grant permissions via ADB.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;adb shell pm grant com.example android.permission.CAMERA
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures smooth test execution without interruptions.&lt;/p&gt;
&lt;h3 id=&quot;14-screenshots-on-failure&quot;&gt;14. Screenshots on Failure&lt;/h3&gt;
&lt;p&gt;Capture screenshots on test failures to debug issues effectively.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;        byte[] screenShots = Driver.getDriver().getScreenshotAs(OutputType.BYTES);

        //Appium will always return screenshot as png
        File saveFile = new File(&quot;C:\\Users\\YourPath\\screenshot.png&quot;);

        //save to our desktop if needed
        try (FileOutputStream fos = new FileOutputStream(saveFile)) {
            fos.write(screenShots);
        } catch (IOException e) {
            e.printStackTrace();
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This helps in analyzing failures visually.&lt;/p&gt;
&lt;h3 id=&quot;15-test-data-cleanup&quot;&gt;15. Test Data Cleanup&lt;/h3&gt;
&lt;p&gt;Ensure a fresh app state before every test by resetting app data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;driver.resetApp();
// Or if you dont have complex use cases and dont want to handle before-after methods at hooks in your Driver class use
options.setNoReset(false);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This prevents stale data from affecting test results.&lt;/p&gt;
&lt;h3 id=&quot;16-cloud-testing-services&quot;&gt;16. Cloud Testing Services&lt;/h3&gt;
&lt;p&gt;Use services like BrowserStack, Sauce Labs, or Firebase Test Lab to run tests on real devices in the cloud. It will also help you if you are unable to use Mac machine to test IOS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;capabilities.setCapability(&quot;browserstack.user&quot;, &quot;your_username&quot;);
capabilities.setCapability(&quot;browserstack.key&quot;, &quot;your_access_key&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cloud testing provides access to multiple device configurations and reduces infrastructure costs.&lt;/p&gt;
&lt;h3 id=&quot;bonus-ios-tips&quot;&gt;Bonus: iOS Tips&lt;/h3&gt;
&lt;h4 id=&quot;use-xcuitest-automation-engine&quot;&gt;Use &lt;code&gt;xcuitest&lt;/code&gt; Automation Engine&lt;/h4&gt;
&lt;p&gt;For iOS automation, always use the &lt;code&gt;XCUITest&lt;/code&gt; automation engine as it is the most stable and widely supported.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;capabilities.setCapability(&quot;automationName&quot;, &quot;XCUITest&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures better compatibility with iOS devices.&lt;/p&gt;
&lt;h4 id=&quot;handle-ios-permissions-automatically&quot;&gt;Handle iOS Permissions Automatically&lt;/h4&gt;
&lt;p&gt;iOS apps require permissions for features like camera and location. You can pre-approve these using Appium capabilities.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;capabilities.setCapability(&quot;autoAcceptAlerts&quot;, true);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This prevents permission popups from interrupting your tests.&lt;/p&gt;
&lt;h4 id=&quot;use-predicate-strings-for-locators&quot;&gt;Use Predicate Strings for Locators&lt;/h4&gt;
&lt;p&gt;Instead of XPaths, use &lt;code&gt;Predicate Strings&lt;/code&gt; for better performance and stability.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;driver.findElement(MobileBy.iOSNsPredicateString(&quot;label == 'Submit'&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Predicate Strings execute faster and are more robust than XPath.&lt;/p&gt;
&lt;h4 id=&quot;use-iosclasschain-for-faster-element-finding&quot;&gt;Use iosClassChain for Faster Element Finding&lt;/h4&gt;
&lt;p&gt;For better performance in iOS automation, prefer &lt;code&gt;iosClassChain&lt;/code&gt; instead of XPath. It’s more efficient and faster for locating elements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;driver.findElement(MobileBy.iOSClassChain(&quot;**/XCUIElementTypeButton[`label == 'Submit'`]&quot;)).click();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This improves execution speed compared to XPath and is more reliable.&lt;/p&gt;
&lt;h3 id=&quot;predicate-string-vs-iosclasschain&quot;&gt;Predicate String vs iOSClassChain&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use Predicate String when you need more readable and flexible conditions (e.g., filtering by label, value, or name).&lt;/li&gt;
&lt;li&gt;Use iosClassChain when dealing with deeply nested elements or hierarchical structures (e.g., finding a button inside a specific cell).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;TL&amp;amp;DR:&lt;/strong&gt; Predicate String for simple queries, iosClassChain for complex UI trees.&lt;/p&gt;
&lt;p&gt;If performance is a concern, iosClassChain is generally faster than Predicate Strings, especially for deeply nested elements.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Following these best practices will significantly improve the stability, reliability, and efficiency of your Appium-based mobile test automation.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Let me know if you have other tips as well!&lt;/em&gt;&lt;/p&gt;
</description>
<category>QA Best Practices</category>
<guid isPermaLink="true">https://coderlegion.com/1762/android-ios-testing-perfected-20-appium-tricks-you-need</guid>
<pubDate>Tue, 01 Apr 2025 17:16:31 +0000</pubDate>
</item>
</channel>
</rss>