iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 27
0
Mobile Development

從0開始,全方面自動化測試Android App系列 第 27

[Day 27] 利用Appium測試Android App (二)

  • 分享至 

  • xImage
  •  

昨天介紹過Appium Inspector的使用方式後,今天再來開始寫Appium語法會快速很多。寫Appium可以用很多語法,因我們是Android開發者,所以我這邊選擇JVM的版本來開發,語法用Java或是Kotlin都可以。我選擇的開發工具是一樣是由Jetbrains開發的IDE IntelliJ,不使用Android Studio的原因是因為我不是開發Android App,用Android Studio來開發會變成是小題大作,專案內的SDK都不會用到。而且IntelliJ的開發介面和習慣跟Andoid Studio差不多,大家應該可以很快上手。

我們在IntelliJ裡建立一個新的maven專案,然後在src/java/test/資料夾中新增一個UnitTest.kt的檔案。
https://ithelp.ithome.com.tw/upload/images/20191011/20120975mbHHs1Kl0n.png

另外在pom檔裡面要加入下面的dependecies,第一個dependency就是appium,第三及第四個的dependency是看JUnit的部份要選擇用kotlin還是java開發,擇一即可。

<dependencies>
        <!-- appium -->
        <dependency>
            <groupId>com.github.appium</groupId>
            <artifactId>java-client</artifactId>
            <version>7.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
        <!-- kotlin version -->
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-test-junit</artifactId>
            <version>${kotlin.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- java version -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

當denpendency都設置完成後,我們就可以開始來寫Appium test的語法了。還記得昨天講的inspector launch application的參數嗎?在Appium裡被稱為Capability,回去看看昨天講的inspector裡的參數是不是也寫上capability。我們要動態讓Appium呼叫APK起來測試也是透過capability的設置,這裡只要把昨天提到的capabilities依序填入即可。

我們要回傳的物件是AndroidDriver,第一個參數是Appium Server的URL物件,如果我們不改Appium Server的預設URL那就是http://127.0.0.1:4723/wd/hub ,第二個參數需傳入用DesiredCapabilities()包裝起來的capabilities。這個AndroidDriver要做的事就是告訴Appium Server開啟capabilities的設定。

AndroidDriver(URL("http://127.0.0.1:4723/wd/hub"), capabilities)

fun getAppiumDriver(): AndroidDriver<AndroidElement> {
    val capabilities = DesiredCapabilities().apply {
        setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID)
        setCapability(MobileCapabilityType.DEVICE_NAME, "Pixel2")
        setCapability(AndroidMobileCapabilityType.AUTO_GRANT_PERMISSIONS, true)
        setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2)
        setCapability(MobileCapabilityType.APP, "/Users/danielchen/Desktop/app-debug.apk")
    }
    return AndroidDriver(URL("http://127.0.0.1:4723/wd/hub"), capabilities)
}

在Test class裡我們跟之前一樣在function前加上Test的annotation告訴JUnit我們要測試,再來我們透過剛剛講的AndroidDriver的回傳物件來操作元件測試。針對我們有用到的語法說明如下。

  • manage().timeouts().implicitlyWait 因為設備的性能或網路連線的關係,導致被測元件尚未出現於畫面中,所以設定每個指令最長的retry時間。
  • findElementById 利用id來尋找元件reference,可以直接看source code或用inspector來找
  • findElementsByPath 利用xpath來尋找元件清單(RecyclerView)的reference,如果確認畫面只有一個元件可用findElementByPath就好
  • click 點擊元件
  • sendKeys 對元件輸入字串
  • text 找出元件的text屬性
class UnitTest {
    @Test
    fun testAppium() {
        getAppiumDriver().apply {
            manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS) //設定每個動作的最長等待時間
            findElementById("button").click() //進入MainActivity後透過ID尋找button元件並呼叫click點擊
            //進入ListActivity後利用xpath抓取RecyclerView裡的元件(請參閱Day25的說明明
            val userList = findElementsByXPath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/androidx.recyclerview.widget.RecyclerView/android.widget.LinearLayout\n") 
            //我們click第一個item
            userList[0].click()
            //進入DetailActivity後抓取editText並輸入God
            findElementById("editText").sendKeys("God")
            //找到Button元件點擊
            findElementById("button").click()
            //最後用assertEquals方式判斷textView裡的字串是不是跟預期一樣。
            assertEquals(findElementById("textView").text, "God is level 10")
        }
    }
}

結論

我們很快就完成了一個e2e的測試,你有沒有發現我們沒有寫到任何一行Android SDK的程式,只要拿了build好的APK就完成了這次的測試,很神奇吧。透過Appium的測試我們可以讓不會寫Android或IOS的人加入測試的行列,也可以讓各自平台的工程師用更快速的方法來寫e2e測試。以Andriod平台來說,用Appium開發比用Espresso簡單很多,雖然performance會差一點點,必竟一個是native控制一個是透過web selenium去轉發,但開發時間就有顯著的差異了。

而e2e test一個很重要的特點是模擬使用者的行為,大家都知道Android phone的特色就是各家廠商都在framework層有不同程度的客制化,A手機執行沒問題不代表B手機執行沒問題,所以在不同的device上測試也很重要。但我們不可能只為了測試就不斷購入不同的手機,下一節我們來聊聊寫好了Appium有沒有什麼Cloud Service能讓我們更方便進行不同設備e2e的測試。


上一篇
[Day 26] 利用Appium測試Android App (一)
下一篇
[Day 28] 使用AWS Device Farm來測試App
系列文
從0開始,全方面自動化測試Android App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言