บทที่ 4: AppiumLibrary Keywords — เทียบกับ SeleniumLibrary¶
Pre-chapter Retrieval¶
ก่อนอ่านบทนี้ ลองตอบก่อน:
ใน capabilities คุณต้องบอก Appium อะไรบ้างเพื่อให้ session เริ่มได้? และ
appium:prefix ใช้เมื่อไหร่?
ดูเฉลย
ต้องบอก platformName, automationName, deviceName, appPackage, appActivity (สำหรับ Android native app) — capabilities ที่เฉพาะ Appium ต้องมี `appium:` prefix ตาม W3C standard ยกเว้น `platformName` ที่เป็น W3C standard อยู่แล้ววัตถุประสงค์¶
อ่านจบบทนี้แล้วคุณจะ:
- เทียบ keyword ของ SeleniumLibrary กับ AppiumLibrary ได้แบบ 1:1
- ใช้ keyword หลักของ AppiumLibrary ได้: Open Application, Click Element, Input Text, Page Should Contain Element
- เข้าใจว่า keyword ไหนเหมือน ไหนต่าง ไหนมีเฉพาะ mobile
- เขียน test case พื้นฐานสำหรับ mobile app ได้
ทำไมต้องรู้? (Why)¶
นี่คือ "good news" สำหรับคนที่รู้ RF + Selenium มาแล้ว
AppiumLibrary ออกแบบมาให้ keyword คล้ายกับ SeleniumLibrary มากที่สุด — เพราะทั้งสองใช้ W3C WebDriver protocol เดียวกัน
ดังนั้นคุณไม่ได้เริ่มจากศูนย์ — คุณเริ่มจาก ~70% ที่รู้อยู่แล้ว
Analogy: เปลี่ยนรถแต่ใช้ใบขับขี่เดิม¶
เรียน AppiumLibrary เหมือนคนที่ขับรถเก๋ง (Selenium/web) มาตลอด แล้วต้องขับ SUV (Appium/mobile)
- กฎจราจร = เหมือนกัน (W3C WebDriver protocol)
- วิธีขับเบื้องต้น = เหมือนกัน (click, input text, assertions)
- พวงมาลัย/เบรค = ต่างกันนิดหน่อย (locator strategies)
- ฟีเจอร์พิเศษ = SUV มี 4WD ที่รถเก๋งไม่มี (gesture, touch actions)
⚠️ ถ้าเชื่อ analogy นี้ 100% จะเข้าใจผิดว่า: - ทุก keyword เหมือนกันหมด → มี keyword บางตัวที่ AppiumLibrary ไม่มี (เช่น Select Frame ซึ่งเป็น web concept) - Locator เหมือนกัน → mobile ใช้ locator strategies ที่ต่างออกไป (เรียนละเอียดในบทที่ 5)
เนื้อหาหลัก¶
ตารางเปรียบเทียบ: SeleniumLibrary vs AppiumLibrary¶
| หน้าที่ | SeleniumLibrary | AppiumLibrary |
|---|---|---|
| เปิด session | Open Browser |
Open Application |
| ปิด session | Close Browser |
Close Application |
| คลิก element | Click Element |
Click Element ✅ เหมือนกัน |
| พิมพ์ข้อความ | Input Text |
Input Text ✅ เหมือนกัน |
| อ่านข้อความ | Get Text |
Get Text ✅ เหมือนกัน |
| ตรวจ element มีอยู่ | Page Should Contain Element |
Page Should Contain Element ✅ เหมือนกัน |
| รอ element | Wait Until Element Is Visible |
Wait Until Element Is Visible ✅ เหมือนกัน |
| รอ element หายไป | Wait Until Element Is Not Visible |
Wait Until Element Is Not Visible ✅ เหมือนกัน |
| เปิด URL | Go To |
Go To Url (mobile web เท่านั้น) |
| Swipe | ❌ ไม่มี | Swipe ✅ mobile only |
| Scroll | ❌ ไม่มี | Scroll ✅ mobile only |
| Long Press | ❌ ไม่มี | Long Press ✅ mobile only |
| Lock device | ❌ ไม่มี | Lock ✅ mobile only |
| เปิด/ปิด keyboard | ❌ ไม่มี | Hide Keyboard ✅ mobile only |
Keyword ที่ใช้บ่อยที่สุด¶
Open Application¶
Open Application http://localhost:4723
... platformName=Android
... appium:automationName=UIAutomator2
... appium:deviceName=emulator-5554
... appium:appPackage=com.example.app
... appium:appActivity=.MainActivity
"Opens a new application to the given Appium server" (AppiumLibrary docs)
Click Element¶
Click Element accessibility_id=login_button
Click Element id=com.example.app:id/btn_submit
Click Element xpath=//android.widget.Button[@text='Login']
"Clicks the element identified by locator." (AppiumLibrary docs)
Input Text¶
Input Text accessibility_id=username_field john@email.com
Input Text id=com.example.app:id/et_password secret123
"Types the given text into the text field identified by locator." (AppiumLibrary docs)
Page Should Contain Element / Element Should Be Visible¶
Page Should Contain Element accessibility_id=home_screen
Element Should Be Visible id=com.example.app:id/tv_welcome
Wait Until Element Is Visible¶
Get Text¶
${balance}= Get Text accessibility_id=account_balance
Should Be Equal As Strings ${balance} ฿10,000.00
ตัวอย่าง 3 ระดับ¶
Beginner: Test case ง่ายๆ — เปิดแอปและตรวจ element¶
# tested: Robot Framework 7.x, AppiumLibrary 3.0.0, Android API 33 emulator
# requires: emulator รันอยู่, Appium server รันอยู่
*** Settings ***
Library AppiumLibrary
*** Variables ***
${APPIUM} http://localhost:4723
${PKG} com.example.app
${ACT} .MainActivity
*** Test Cases ***
เปิดแอปและตรวจว่า Login screen ขึ้น
[Setup] Open Application ${APPIUM}
... platformName=Android
... appium:automationName=UIAutomator2
... appium:deviceName=emulator-5554
... appium:appPackage=${PKG}
... appium:appActivity=${ACT}
Page Should Contain Element accessibility_id=username_input
Page Should Contain Element accessibility_id=password_input
Page Should Contain Element accessibility_id=login_button
[Teardown] Close Application
Intermediate: Login flow ครบ + error case¶
# tested: Robot Framework 7.x, AppiumLibrary 3.0.0
# requires: app ที่มี login screen พร้อม username/password field
*** Settings ***
Library AppiumLibrary
*** Variables ***
${APPIUM} http://localhost:4723
${PKG} com.example.app
${ACT} .MainActivity
*** Keywords ***
เปิดแอป
Open Application ${APPIUM}
... platformName=Android
... appium:automationName=UIAutomator2
... appium:deviceName=emulator-5554
... appium:appPackage=${PKG}
... appium:appActivity=${ACT}
ทำการ Login ด้วย
[Arguments] ${username} ${password}
Wait Until Element Is Visible accessibility_id=username_input 10s
Input Text accessibility_id=username_input ${username}
Input Text accessibility_id=password_input ${password}
Click Element accessibility_id=login_button
*** Test Cases ***
Login สำเร็จ
[Setup] เปิดแอป
ทำการ Login ด้วย valid_user valid_pass
Wait Until Element Is Visible accessibility_id=home_screen 15s
Page Should Contain Element accessibility_id=home_screen
[Teardown] Close Application
Login ล้มเหลว — password ผิด
[Setup] เปิดแอป
ทำการ Login ด้วย valid_user wrong_pass
Wait Until Element Is Visible accessibility_id=error_message 10s
${error}= Get Text accessibility_id=error_message
Should Contain ${error} Invalid credentials
[Teardown] Close Application
Advanced: Keyword ที่ handle loading state อย่างมืออาชีพ¶
# tested: Robot Framework 7.x, AppiumLibrary 3.0.0
# pattern นี้ใช้กับ app ที่มี loading spinner
*** Settings ***
Library AppiumLibrary
*** Keywords ***
รอให้ Loading หายไปและ Element ขึ้น
[Arguments] ${element_locator} ${timeout}=30s
# รอ loading spinner หายก่อน (ถ้ามี)
Run Keyword And Ignore Error
... Wait Until Element Is Not Visible accessibility_id=loading_spinner ${timeout}
# แล้วค่อยรอ element ที่ต้องการ
Wait Until Element Is Visible ${element_locator} ${timeout}
Element Should Be Enabled ${element_locator}
ทดสอบ Transfer Money Flow
[Setup] เปิดแอป
ทำการ Login ด้วย test_user test_pass
รอให้ Loading หายไปและ Element ขึ้น accessibility_id=transfer_button
Click Element accessibility_id=transfer_button
รอให้ Loading หายไปและ Element ขึ้น accessibility_id=recipient_field
Input Text accessibility_id=recipient_field 0812345678
[Teardown] Close Application
Common Mistakes¶
❌ ใช้ Open Browser แทน Open Application
→ Browser เปิดขึ้น แต่ไม่ใช่ mobile app ที่ต้องการทดสอบ
✅ AppiumLibrary ใช้ Open Application และต้องระบุ Appium server URL เป็น argument แรก
(source: serhatbolsu.github.io/robotframework-appiumlibrary)
❌ ไม่มี Wait — click ทันทีที่ app เปิด
→ App ยังโหลดไม่เสร็จ ✅ ใช้Wait Until Element Is Visible ก่อน interact เสมอ — app ใช้เวลา load
(source: AppiumLibrary best practice)
❌ ไม่ใส่ Close Application ใน Teardown
→ Session ค้างอยู่ → test ถัดไป session conflict
✅ ใส่ Close Application ใน [Teardown] ทุก test case เสมอ
(source: serhatbolsu.github.io/robotframework-appiumlibrary)
❌ copy locator จาก web มาใช้กับ mobile
✅ Mobile native app ใช้ accessibility_id, resource-id, หรือ xpath — CSS selector ใช้ได้กับ mobile web เท่านั้น (source: บทที่ 5 เรื่อง locators)สรุปบท¶
ลองตอบก่อนดูเฉลย:
คำถาม 1: keyword
Input Textของ AppiumLibrary กับ SeleniumLibrary เหมือนหรือต่างกัน? และถ้าใช้ SeleniumLibrary อยู่แล้วจะต้องเรียนใหม่ไหม?คำถาม 2: ทำไมต้องใช้
Wait Until Element Is Visibleก่อนClick Elementบน mobile app? บน web ก็ต้องทำแบบนี้ไหม?คำถาม 3: ถ้า test case ของคุณ fail เพราะ element not found — สิ่งแรกที่ควร debug คืออะไร?
ดูเฉลย
**เฉลย 1:** `Input Text` เหมือนกันเลย (signature เดียวกัน, ชื่อเดียวกัน) ความต่างหลักอยู่ที่ locator strategy ที่ใช้ — mobile ไม่รับ CSS selector แต่รับ accessibility_id และ resource-id แทน ดังนั้นต้องเรียนเรื่อง locators ใหม่ แต่ไม่ต้องเรียน keyword ใหม่ **เฉลย 2:** Mobile app มี loading time มากกว่า web — transition ระหว่าง screen, API call, animation ทำให้ element ยังไม่พร้อมเมื่อ click ถึงแม้ web ก็ควรทำ แต่ mobile เป็นปัญหาบ่อยกว่ามาก **เฉลย 3:** ดู screenshot ของ app ณ ตอนที่ fail (Appium สามารถถ่าย screenshot ได้) เพื่อดูว่า UI ตอนนั้นแสดงอะไร จากนั้นตรวจว่า locator ถูกต้องโดยใช้ Appium Inspectorบทต่อไป: บทที่ 5 — Mobile Locators