don't stop believing

Appium Client for Native App (by Python, with Selenium) 본문

Testing Automation/Appium

Appium Client for Native App (by Python, with Selenium)

Tongchun 2018. 8. 6. 15:43

Appium을 이용해 Native App을 컨트롤 하는 Client (Python)을 작성해 보겠습니다.


이 Post를 보시는 분은 Appium Command Line Server와 Appium Client (by Python) 까지 보셨을거라 생각합니다. Kakao Game SDK Test App의 스크립트를 그대로 이어서 진행하겠습니다.


테스트 시나리오는 Kakao Game SDK Test App의 로그인과 로그아웃입니다.


시작 하기에 앞서 Inspector로 각 화면의 Object에 대한 ID 또는 XPath를 확인하겠습니다.



USB로 연결된 디바이스에 Kakao Game SDK Test App을 실행시키 겠습니다.



먼저 보시는 화면의 Desired Capabilities에서 지정한 appActivity(com.kakaogame.sample.SampleActivity)입니다.

왼쪽 화면창에서 로그인 버튼을 클릭하면 버튼 Object가 선택되고 가운데 App Source와 왼쪽 Selected Element를 확인할 수 있습니다.


App Source

<android.widget.Button resource-id="com.kakaogame.sample:id/login_ui_button">


xpath

/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout[2]/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.ScrollView/android.widget.LinearLayout/android.widget.Button[4]


Inspector의 오른쪽 화면 창에서 Object를 선택하면 왼쪽 Selected Element 창에 Tap, Send Keys, Clear의 명령을 줄 수 있습니다.

Login 버튼을 지정하고 Tap을 눌러 화면을 이동 합니다.


화면에 보이는 Object 중 id가 유일한 경우 왼쪽 Selected Element 창의 id 영역에 id가 보이게 됩니다. 하지만 아래 화면처럼 동일한 id가 있을 경우 id는 보이지 않고 xpath만 보여지게 됩니다.



"카카오 계정으로 로그인"을 클릭하고 App Source와 Selected Element를 확인합니다.


App Source

<android.widget.TextView resource-id="com.kakaogame.sample:id/kakao_game_login_idp_item_name">


xpath

/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.FrameLayout[1]/android.widget.RelativeLayout/android.widget.TextView


Tap을 눌러 다음으로 이동 합니다.

디바이스에 카카오톡이 설치되어 있는 경우라면 아래와 같은 화면이 나옵니다. 현재 설치된 카카오톡 계정으로 로그인 할 것인지 다른 카카오 계정으로 로그인 할 것인지를 선택하게 합니다.



저는 다른 카카오계정으로 로그인을 선택하겠습니다.


App Source

<android.widget.TextView resource-id="com.kakaogame.sample:id/login_method_text">


xpath

/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.ListView/android.widget.LinearLayout[2]/android.widget.TextView


Tap을 눌러 다음 화면으로 넘어가면 계정을 입력하게 됩니다.



이메일 또는 전화번호를 클릭해 선택하고 Selected Element 창에 있는 Send Keys를 클릭합니다.



Send Keys창이 나오면 로그인 할 카카오 계정을 입력합니다. 그리고 비밀번호도 동일하게 Send Keys로 입력합니다.


이메일과 비밀번호를 입력하는 창의 App Source가 <android.widget.EditText>로 동일한 것을 볼 수 있습니다. 이럴 경우 xpath를 사용해 object를 확인해 줘야 합니다.


이메일 또는 전화번호 입력 창

App Source

<android.widget.EditText>


Selected Element

/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View[2]/android.view.View[1]/android.view.View[1]/android.widget.EditText


비밀번호(4~32자리) 입력 창

App Source

<android.widget.EditText>


Selected Element

/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View[2]/android.view.View[1]/android.view.View[3]/android.widget.EditText



로그인 버튼을 클릭하고 App source와 Selected Element를 확인해 줍니다.


App Source

<android.view.View>


xpath

/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View[2]/android.view.View[2]


Tap을 눌러 카카오 계정으로 로그인 합니다.



Kakao Game SDK Test App 화면이 나옵니다. 계정에 대한 정보가 보이네요.

이제 로그아웃을 하겠습니다. 동일하게 logout 버튼을 선택하고 App Source와 Selected Element를 확인 합니다.


App Source

<android.widget.Button resource-id="com.kakaogame.sample:id/zinny_sdk_api_button">


xpath

/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout[2]/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.support.v4.view.ViewPager/android.widget.ListView/android.widget.FrameLayout[7]/android.widget.Button


Tap을 클릭해 다음으로 넘어 갑니다. 

로그아웃을 하겠냐고 다시한번 묻는 창이 나옵니다. 로그아웃 버튼을 클릭하고 App Source와 Selected Element를 확인합니다.



App Source

<android.widget.TextView resource-id="com.kakaogame.sample:id/kakao_game_sdk_logout_btn_ok">


xpath

/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.TextView[2]



그럼 로그아웃 후 첫 화면이 나옵니다.



Start 버튼을 클릭해 App Source와 Selected Ement를 확인합니다.


App Source

<android.widget.Button resource-id="com.kakaogame.sample:id/start_button">


xpath

/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout[2]/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.ScrollView/android.widget.LinearLayout/android.widget.Button


이제 여기까지 확인한 App Source와 xpath로 Appium Client를 작성해 보겠습니다.


'''
Kakao Game SDK Test App
Device: V10 (LGF600Kb1134738)
'''
import unittest
import os
from appium import webdriver
from time import sleep
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
 
class KakaoGameSDKLoginOutTest(unittest.TestCase):
 
    def setUp(self):
        
        # Kakao Game SDK Test App 경로
        app = os.path.join(os.path.dirname(__file__), 'D:\\Test_Appium\\KakaogameSDK', 'KakaoGameSDK_Test_App_3.8.0.1.apk')
        app = os.path.abspath(app)

        # Set up appium
        # Appium 서버의 포트는 4001로 지정합니다.
        # 그리고 desired_capabilities에 연결하려는 디바이스(V10)의 정보를 넣습니다.
        self.driver = webdriver.Remote(
            command_executor='http://127.0.0.1:4001/wd/hub',
            desired_capabilities={
                'app': app,
                'platformName': 'Android',
                'platformVersion': '6.0',
                'deviceName': 'V10',
                'automationName': 'Appium',
                'appPackage': 'com.kakaogame.sample',
                'appActivity': 'com.kakaogame.sample.SampleActivity',
                'udid': 'LGF600Kb1134738'
            })

    def test_search_field(self):

        # appiun의 webdriver를 초기화 합니다.
        driver = self.driver

        # selenium의 WebDriverWait을 사용합니다. element가 나올때 까지 최고 20초까지 기다립니다.
        wait = WebDriverWait(driver, 20)
        
        # Login 버튼을 클릭(탭) 합니다.
        # Login element를 ID로 찾고 클릭할 수 있을 때까지 최대 20초까지 기다립니다.
        sdkLogin = wait.until(EC.element_to_be_clickable((By.ID, 'com.kakaogame.sample:id/login_ui_button')))
        sdkLogin.click()

        # "카카오 계정으로 로그인"을 클릭(탭)합니다.
        kakaoLogin = driver.find_element_by_id('com.kakaogame.sample:id/kakao_game_login_idp_item_name')
        kakaoLogin.click()

        # "다른 카카오계정으로 로그인"을 클릭(탭)합니다.
        # 만약 디바이스에 카카오톡이 설치되어 있지 않다면 try/except문을 사용해 처리해야 합니다.

        try:
            otherKakaoAccount = driver.find_element_by_xpath('/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.ListView/android.widget.LinearLayout[2]/android.widget.TextView')
            otherKakaoAccount.click()
        except NoSuchElementException:
            print('No element found')

        # 계정을 입력합니다.
        # 계정과 비밀번호 입력 화면이 나오기 전 로딩 화면이 뜨게 됩니다.
        # 로딩 할때까지 기다려야 하니 wait.until()함수를 사용합니다.
        account = wait.until(EC.element_to_be_clickable((By.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View[2]/android.view.View[1]/android.view.View[1]/android.widget.EditText')))
        account.click()
        account.send_keys('dejavuwing@gmail.com')

        # 비밀번호를 입력합니다.
        password = driver.find_element_by_xpath('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View[2]/android.view.View[1]/android.view.View[3]/android.widget.EditText')
        password.click()
        password.send_keys('qwert1234%')

        # 로그인 버튼을 클릭(탭)합니다.
        signin = driver.find_element_by_xpath('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.webkit.WebView/android.webkit.WebView/android.view.View/android.view.View[2]/android.view.View[2]')
        signin.click()

        # Kakao Game SDK Test App 화면에서 logout 버튼을 클릭(탭)합니다.
        appLogout = wait.until(EC.element_to_be_clickable((By.XPATH, '/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.RelativeLayout[2]/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.support.v4.view.ViewPager/android.widget.ListView/android.widget.FrameLayout[7]/android.widget.Button')))
        appLogout.click()

        # 다시한번 로그아웃을 확인합니다.
        conformLogout = driver.find_element_by_xpath('/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.TextView[2]')
        conformLogout.click()

        # Start 버튼을 클릭합니다.
        start = driver.find_element_by_id('com.kakaogame.sample:id/start_button')
        start.click()

        sleep(30)

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(KakaoGameSDKLoginOutTest)
    unittest.TextTestRunner(verbosity=2).run(suite)

위와같이 Appium Client를 작성하고 runKakaoGameSDKTest_V10.py라고 저장합니다.


Appium 포트를 4001로 하고 실행해 줍니다.


    


adb로 디바이스가 연결되어 있는지도 확인해 줍니다. adb devices



이제 python으로 작성한 Appium Client를 실행 합니다.

python runKakaoGameSDKTest_V10.py



여기까지 Appium을 이용한 Native App 테스트였습니다.


Comments