Appium AppTest Automate

Appium AppTest Automate – 앱 테스트 자동화

Mobile Application을 자동화 할 수 있는 Appium에 대한 포스팅 입니다.

Selenium을 통해서 모바일 크롬 같은 앱을 컨트롤 할 수 있긴 하지만, Mobile apps (native, hybrid, web apps)을 자동화해야 한다면 Appium을 쓰는 것이 좋습니다.

Appium이 무엇인지부터 알아보겠습니다.

Appium은 네이티브, 하이브리드 및 모바일 웹 앱과 함께 사용하기 위한 오픈 소스 테스트 자동화 프레임워크입니다 .

WebDriver 프로토콜을 사용하여 iOS, Android 및 Windows 앱을 구동합니다.

Appium은 iOS 모바일, Android 모바일 및 Windows 데스크톱 플랫폼에서 기본, 모바일 웹 및 하이브리드 애플리케이션을 자동화하기 위한 오픈 소스 도구입니다.

기본 앱
iOS, Android 또는 Windows SDK를 사용하여 작성된 앱입니다.

모바일 웹 앱
모바일 브라우저를 사용하여 액세스하는 웹 앱입니다(Appium은 iOS 및 Chrome의 Safari 또는 Android의 내장 ‘브라우저 ‘앱 지원).

하이브리드 앱
웹 콘텐츠와 상호 작용할 수 있는 기본 컨트롤인 “webview “에 래퍼가 있습니다.
Apache Cordova
와 같은 프로젝트 를 사용하면 웹 기술을 사용하여 앱을 쉽게 빌드한 다음 네이티브 래퍼에 번들로 묶어 하이브리드 앱을 만들 수 있습니다.

중요하게도 Appium은 “교차 플랫폼 “입니다.

동일한 API를 사용하여 여러 플랫폼(iOS, Android, Windows)에 대한 테스트를 작성할 수 있습니다. 이를 통해 iOS, Android 및 Windows 테스트 스위트 간에 코드를 재사용할 수 있습니다.

Appium이 플랫폼을 “지원 “한다는 의미와 자동화 방식에 대한 자세한 정보는 플랫폼 지원 문서 를 참조하십시오 .

Appium을 통해서 안드로이드와 ios를 모두 테스트 할 수 있다라는 점 !

Multi O/S에 대한 테스트를 쉽게 할 수 있다는 점!

순차적으로 Windows 10 환경에서 Android O/S에 대한 테스트 자동화를 진행할 예정입니다.

 

설치부터 시작

설치해야 되는 것들

Appium을 통해서 모바일 앱을 테스트하기 위해서는 몇 가지 설치해야 되는 것들!

1. Python 3

2. Pycharm

3. Android Studio

4. Appium Desktop

파이썬과 관련된 1,2 번은 Selenium 포스팅 에서 확인

wk아직 설치가 안되신 분은 아래 글을 참고해주세요

https://blog.naver.com/centerho/222530362706

(테스트 할 실제 단말기가 없다면 Virtual device를 써야 되니까..)

실제 단말기를 연결할 때 필요한 ADB (Android Debug Bridge)를 설치 하기 위해 진행해보도록 하겠습니다.


android studio 설치

안드로이드 스튜디오 설치를 위해 아래 링크에 접속합니다.

https://developer.android.com/studio

약관에 동의해주고 다운로드를 진행합니다.

다운로드된 파일을 실행합니다.

다음을 누릅니다.

필요할지도 모르니 virtual device도 체크를 해줍니다.

 

설치할 위치를 지정해줍니다.

설치를 진행합니다.

설치는 끝났고 실행을 해줍니다.

SDK를 추가해줍니다.

SDK 위치를 지정해줍니다.


저는 찾기 쉽게 C 밑에 새로운 폴더를 만들었습니다.

 

동의하고 설치를 진행합니다.

 

설치는 완료되었고 우측에 더보기를 눌러서 SDK Manager를 열어서 설치 내역을 확인해봅니다.

 

Android Studio가 필요 없다고 생각되시면 SDK Platform 도구만 설치하셔도 됩니다.

https://developer.android.com/studio/releases/platform-tools?hl =ko

그리고 SDK를 쓰기 위해서 환경변수 설정을 해줍니다.

윈도우 하단에 검색을 누르시고 ‘고급 시스템 설정 ‘을 찾아서 실행합니다.

 

환경 변수를 눌러줍니다.

시스템 변수에서 ‘path ‘를 찾아서 편집을 눌러줍니다.

아래 부분을 새로 추가해줍니다.

 

그럼 모바일 단말과 제대로 연결이 되는지 확인을 해보겠습니다.

윈도우 검색에서 ‘cmd ‘를 입력해주고 명령프롬프트를 실행합니다.

‘adb ‘를 입력한 후 enter를 해봅니다.

아래와 같은 도움말이 뜬다면 정상적으로 adb를 사용할 준비가 되었습니다.

만약 안된다면 platform-tools 폴더 안에 adb.exe 파일이 있는지

환경 변수 설정이 제대로 된 건지 다시 확인해보시길 바랍니다.

Appium 설치

설치를 위해 appium 홈페이지로 이동 합니다.

https://appium.io/

다운로드 받는 파일을 실행줍니다.

설치를 합니다.

설치가 완료되면 server GUI를 실행 한니다.

기본으로 Port는 4723을 사용합니다.

‘edit configgition’을 눌러서 황셩 설정을 해줍니다.

여기서 ANDROID_HOME과 JAVA_HOME을 설정해줘야 합니다.

Android Home은 아까 SDK를 설치했던 위치를 입력하면 되고 Java는 설치 유무를 확인하기 위해 다시 명령 프롬프트를 켜서 확인을 해봅니다. 아래와 같이 표시 된다면 java가 설치 되있는 것이고 JAVA의 위치를 찾아서 JAVA_HOME에 입력해줍니다.

c:/Users/cente>java –version

java 15.0.1 2023-11-27

Java(TM) SE Runtime Enviroment (buils 15.0.1-9-18)

Java HotSpot(TM) 64-Bit Server VM (build 15.0.1+9-18, mixed mode, sharing)

설치가 안되있다면 아래 링크에서 다운 받아서 설치를 합니다.

https://www.oracle.com/java/technologies/downloads/#jdk17-windows

‘Start Server’ 를 눌러보면

그리고 GUI Inspector를 별도로 설치를 해줘야 됩니다. (예전에는 함께 설치 됐던거 같은데 포스팅을 쓰기 위해 삭제하고 다시 설치해보니 inspector를 별도로 설치하는 걸로 바뀐거 같습니다.)

아래 링크에서 windows용 exe 실행 파일을 다운받으세요 (현재 포스팅을 쓰는 시점에서는 파일명이 Appium-inspector-windows-2022.2.1.exe 입니다.)

https://github.com/appium/appium-inspector/releases

이렇게 준비가 되었으면 appium 설치도 끝!!

모바일 단말기 개발자모드 켜기

테스트에 사용할 단말기의 개발자 모드를 켜줘야 됩니다.

설정 > 휴대전화정보 > 소프트웨어 정보 로 이동해서

설정 > 휴대전화정보 > 소프트웨어 정보 로 이동해서

그럼 개발자옵션이 활성화 되었습니다. 라는 메세지가 뜨고 설정에 다시 가보면 ‘개발자 옵션’ 메뉴가 생긴 걸 확인할 수 있습니다.

개발자 옵션에 들어가서 ‘USB 디버깅’ 을 켜줍니다.

마지막으로

C:Users/cente/adb devices

* daemon not running; starting now at tcp:5037

* daemon started successfully

List of devices attached

R3CR10Z1GHT device ==> 추후 필요

위와 같이 뜬다면 모든 준비는 끝났습니다.

 

Appium을 이용해서 모바일 단말로 연결을 해보겠습니다. 우선 Appium이 어떻게 움직이는지 한번 살펴보겠습니다.

그림에서 볼 수 있듯이 우리가 작성한 Test Script는 Appium 서버를 통해 각 단말기로 실행을 시키게 되고 이어 따른 응답을 다시 Appium 서버를 통해 받을 수 있게 됩니다.

연결을 시작하겠습니다.

1. 단말기를 PC에 연결 합니다(USB 디버깅이 On 상태여야 함) 연결 시 아래와 같은 팝업이 뜬다면 허용을 해주세요

2. 설치된 Appium Server GUI를 실행합니다.

start Server 버튼을 클릭합니다.

아래와 같은 메시지가 보인다면 정상 입니다.

[Appium] Appium REST http interface listener started on 0.0.0.0:4723

3. 다음은 Appium Inspector를 켜줍니다.

아래와 같이 입력해줍니다.

– Remote Host : 127.0.0.1

– Remote Port : 4723

– Remote Path : /wd/hub

그리고 Desired Capabilities를 입력해줘야 합니다.

Desired Capabilities 에 대한 자세한 사항은 아래 문서를 참고하세요

https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md

우선은 2가지만 입력하면 됩니다.

deviceName

platformName

device name은 adb devices 를 통해 얻은 정보 입니다.

C:\Users\cente>adb devices
* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
R3CR10Z1GHT device

입력하면 아래와 같이 됩니다.

 “deviceName” : “R3CR10Z1GHT”,
 “platformName” : “Android”

우측에 JSON 형태로 보여집니다.

자 그럼 이제 Start Session를 눌러줍니다.

아래와 같이 단말기의 화면이 미러링 되서 보여지고

각 영역을 클릭하면 각 Element의 정보들을 확인할 수 있습니다.

여기까지 하면 단말기까지 연결은 완료

단말기 연결을 해서 화면을 미러링하는 거 까지만 했었는데 이제부터는 본격적으로 시작을 하려고 합니다.

진행할 과정은 아래와 같습니다.

python을 이용해서 Android 단말기에 있는 ‘계산기’ 앱을 호출하는 과정을 진행하겠습니다.

Android에 여러 기본 앱 중 계산기 앱을 선택한 이유는 기본적으로 설치되있고 다루기가 쉬울 것 같아서 선택했습니다.

Desired Capabilities 입력하기

처음에 모바일 단말기에 설치되어 있는 앱을 호출하기 위해서는 Desired Capability를 알아야 합니다.

Appium Desired Capability란?

Desired Capabilities are keys and values encoded in a JSON object, sent by Appium clients to the server when a new automation session is requested. They tell the Appium drivers all kinds of important things about how you want your test to work.

https://appium.io/docs/en/writing-running-appium/caps/

다음의 JSON 예제로 확인을 해보면

{
  “platformName”: “iOS”,
  “platformVersion”: “11.0”,
  “deviceName”: “iPhone 7”,
  “automationName”: “XCUITest”,
  “app”: “/path/to/my.app”
}

이 Desired Capabilities는 iOS 11.0이 설치된 iphone7 단말기의 XCUITest라는 드라이버를 사용해서

my.app이라는 앱의 자동화 세션을 시작하게 됩니다.

(출처 : https://appium.io/docs/en/writing-running-appium/caps/)

내 PC에서 Appium Server GUI 를 실행시킨 후 ‘Start Server’로 시작을 합니다.

다음은 Appium inspector를 켠 후

위에서 입력했던 deviceName과 platformName을 다시 적어 준 후 ‘Start Session’을 눌러

단말기 미러링을 시작합니다.

단말기 미러링이 완료되었다면 아래와 같은 화면이 보일 겁니다.

자 이제 단말기에서 ‘계산기’ 앱을 실행시킵니다.

그리고 Inspector 상단 메뉴 중 ‘Refresh’ 버튼을 눌러줍니다.

그럼 아래와 같이 계산기 화면으로 변경된 걸 확인할 수 있습니다.

중앙에 App source를 눌러보면 오른쪽 Selected Element에서

선택한 Element의 정보를 확인할 수 있습니다.

그럼 여기서 이 앱의 package 이름이 com.sec.android.app.popupcalculator’ 라는 것을 확인할 수가 있습니다.

앱의 이름을 알았으니 이제 이 앱을 실행시키는 방법을 찾아봅니다.

내 PC 윈도우의 검색칸에 ‘cmd’를 입력해서 명령 프롬프트를 실행시킵니다.

아래와 같이 입력합니다. (주황색 배경색 참고)

C:\Users\cente>adb shell

p3s:/ $ dumpsys window windows | grep “popupcalculator”

Window #12 Window{3432f8d u0 com.sec.android.app.popupcalculator/com.sec.android.app.popupcalculator.Calculator}:

mOwnerUid=10291 showForAllUsers=false package=com.sec.android.app.popupcalculator appop=NONE

mBaseLayer=21000 mSubLayer=0 mToken=ActivityRecord{f1dfe0e u0 com.sec.android.app.popupcalculator/.Calculator t38329}

mActivityRecord=ActivityRecord{f1dfe0e u0 com.sec.android.app.popupcalculator/.Calculator t38329}

WindowStateAnimator{37a6c59 com.sec.android.app.popupcalculator/com.sec.android.app.popupcalculator.Calculator}:

mInputMethodInputTarget in display# 0 Window{3432f8d u0 com.sec.android.app.popupcalculator/com.sec.android.app.popupcalculator.Calculator}

inputMethodControlTarget in display# 0 Window{3432f8d u0 com.sec.android.app.popupcalculator/com.sec.android.app.popupcalculator.Calculator}

topApp=ActivityRecord{f1dfe0e u0 com.sec.android.app.popupcalculator/.Calculator t38329}

snapshot=TaskSnapshot{ mId=1654844112125 mTopActivityComponent=com.sec.android.app.popupcalculator/.Calculator mSnapshot=android.graphics.GraphicBuffer@df9701e (1440×3200) mColorSpace=sRGB IEC61966-2.1 (id=0, model=RGB) mOrientation=1 mRotation=0 mTaskSize=Point(1440, 3200) mContentInsets=[0,100][0,168] mIsLowResolution=false mIsRealSnapshot=true mWindowingMode=1 mSystemUiVisibility=8208 mIsTranslucent=false

첫번째 줄을 보면

com.sec.android.app.popupcalculator 뒤에 com.sec.android.app.popupcalculator.Calculator 부분이 (청색 배경색)

실행하는 방법으로 보입니다.

즉 app package에 Calculator를 추가해주면 됩니다.

이제 필요한 정보는 다 얻은 것 같습니다.

다시 Appium Inspector로 돌아가서 현재 연결되어 있는 세션을 종료한 후

다음과 같이 입력 해줍니다.

그리고 ‘Start Session’을 누르기 전에

단말기에 켜놨던 계산기 앱을 종료해줍니다.

그럼 Start Sesssion을 눌러보면 아래와 같이 실행이 될 것입니다.

Python Scripting

이제 준비는 끝났습니다.

아까 작성한 JSON 값을 복사해놓습니다.

{

  “appium:deviceName”: “R3CR10Z1GHT”,

  “platformName”: “Android”,

  “appium:appPackage”: “com.sec.android.app.popupcalculator”,

  “appium:appActivity”: “com.sec.android.app.popupcalculator.Calculator”

}

Pycharm으로 가서 새로운 Project를 생성합니다.

저는 ‘mobileTest’라는 새로운 프로젝트를 생성 했습니다.

제일 먼저 Appium을 설치를 해야겠죠?

Pycharm 상단 메뉴를 통해서 File>Settings > Project: mobileTest > python Interpreter 로 가서

‘Appium-Python-Client’ 를 Install 해줍니다.

새로운 python 파일을 만들겠습니다.

저는 test.py 라고 간단히 만들었습니다.

제일 먼저 해야 될 것은 appium 패키지에 webdriver 모듈을 불러와야 됩니다.

다음은 아까 복사해둔 desired_capabilities를 입력합니다.

저는 간단하게 desired_cap 이라고 정했습니다.

다음은 webdriver를 인스턴스로 만들어줍니다.

webdriver를 path는 local host의 4723 포트로 desired_cap 값을 가지고 실행하면 됩니다.

(이 값들은 Appium server와 Inspector를 보면 아실 수 있습니다.)

전체 코드는 다음과 같습니다.

from appium import webdriver

desired_cap = {

  “appium:deviceName”: “R3CR10Z1GHT”,

  “platformName”: “Android”,

  “appium:appPackage”: “com.sec.android.app.popupcalculator”,

  “appium:appActivity”: “com.sec.android.app.popupcalculator.Calculator”

}

driver = webdriver.Remote(“http://localhost:4723/wd/hub”, desired_cap)

Run을 시켜보겠습니다. (Alt + Shift + F10)

아까 Inspector로 Session을 연결한 것과 동일한 결과를 얻을 수 있습니다.

App을 실행시킬 수 있으니 이제 다음은 App에서 Action으로 컨트롤 하고 결과값에 대한 검증만 할 수 있으면 되겠습니다.

test로 만들었던봤던 code는 앞으로 driver로 쭈욱 사용해야 되기 때문에 모듈로 만들어놓도록 하겠습니다.

package 폴더를 하나 만들어서 test.py는 그곳으로 옮기도록 하겠습니다.

그리고 파일명을 ‘webDriver.py’로 변경합니다. (특별히 중요한 내용은 아니니 이름은 아무거나 ^^)

web driver를 호출하는 부분을 함수로 지정하고 wd라는 인스턴스에 저장하게 합니다.

그리고 혹시 모르니 앱이 뜨기 까지 10초간 기다리는 부분도 추가해줍니다.

정리하면 아래와 같은 모습이 됩니다.

from appium import webdriver
desired_cap = {
  “appium:deviceName”: “R3CR10Z1GHT”,
  “platformName”: “Android”,
  “appium:appPackage”: “com.sec.android.app.popupcalculator”,
  “appium:appActivity”: “com.sec.android.app.popupcalculator.Calculator”
}
def cal():
  wd = webdriver.Remote(“http://localhost:4723/wd/hub”, desired_cap)
  wd.implicitly_wait(10)
  return wd

그럼 이제 test case들을 만들 새로운 폴더를 하나 만들고 그 안에 test_1.py라는 파일을 만들겠습니다.

계산기 앱을 호출하기 위해서는 아래 코드만 써주면 됩니다.

from configuration import webDriver
webDriver.cal()

(단말기와 연결을 위해서는 appium server gui에서 Start server를 항상 먼저 해주어야 합니다.)

alt+shift+f10 을 눌러서 실행해보면 이전과 동일하게 계산기 앱이 뜨는 걸 확인할 수 있습니다.

그럼 이제 본격적으로 앱에서 사용할 수 있는 action 들에 대해서 알아보도록 하겠습니다.

Touch Action

우리 모바일 폰에서 쓰는 터치 행동들을 유심히 생각해보면

손가락으로 누르고 / 이동하고 / 다시 띠고 => press / move to / release

탭 하고 => tap

길게 누르고 => long press

등이 있습니다.

먼저 탭을 해보겠습니다.

터치를 하기 위해서는 TouchAction 이라는 모듈이 필요합니다.

TouchAction을 import 해주고

TouchAction에 web drvier를 담아서 action 이라는 인스턴스를 만들어줍니다.

다음 action에 x=100, y=100부터 100단위로 x=500, y=500 좌표까지 탭하는 코드를 작성해보겠습니다.

(touch 액션 마지막에는 항상 perform 을 붙여줘야 수행이 됩니다.)

from configuration import webDriver

from appium.webdriver.common.touch_action import TouchAction

wd = webDriver.cal()

# tap

action = TouchAction(wd)

action.tap(x=100, y=100).perform()

action.tap(x=200, y=200).perform()

action.tap(x=300, y=300).perform()

action.tap(x=400, y=400).perform()

action.tap(x=500, y=500).perform()

 

이번에는 tap으로 계산기의 숫자를 눌러보겠습니다.

7번 숫자의 좌표를 보니 대략 x=215, y=1995 정도 되는 것 같습니다.

7을 세번 눌러 보겠습니다.

from configuration import webDriver
from appium.webdriver.common.touch_action import TouchAction
import time
wd = webDriver.cal()
# tap
action = TouchAction(wd)
action.tap(x=215, y=1995).perform()
action.tap(x=215, y=1995).perform()
action.tap(x=215, y=1995).perform()

이번에는 복합적으로 누르고 / 이동하고 / 띠는 드래그 동작을 해보겠습니다.

x= 700, y =700에서 누르고 x=700, y=1400까지 이동한다음에 띠는 동작을 해보겠습니다.

from configuration import webDriver
from appium.webdriver.common.touch_action import TouchAction
import time
wd = webDriver.cal()
# tap
action = TouchAction(wd)
action.press(x=700, y=700).move_to(x=700, y=1400).release().perform()
이외에도 여러 액션들이 있으니 한번 찾아서 해보시면 쉽게 아실 수 있을 것 같습니다.


Key code

다음은 터치가 아니라 키를 통해서 입력을 해보도록 하겠습니다.

press_keycode란 함수가 있고 내장함수라 별도 import 과정은 필요가 없습니다.

key code의 값은 숫자 1이 코드 1은 아닙니다.

keycode의 값은 아래 페이지를 참고하세요

https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_0

위 페이지를 참고해보면

keycode로 0은 숫자 7

keycode로 9는 숫자 17을 넣어줘야 합니다.

계산기에서 숫자 0부터 숫자 9까지 입력하는 동작을 해보도록 하겠습니다.

from configuration import webDriver
from appium.webdriver.common.touch_action import TouchAction
import time
wd = webDriver.cal()
# tap
# action = TouchAction(wd)
# action.press(x=700, y=700).move_to(x=700, y=1400).release().perform()
for i in range(7, 17):
wd.press_keycode(i)

객체 인식

마지막으로는 직접 화면에서 객체를 찾아서 클릭하거나 값을 입력하는 방법 입니다.

폰에서 계산기 화면을 켜놓고 ‘appium inspector’를 켜줍니다.

start session을 해서 미러링을 시작합니다

계산기 화면이 미러링 되고 있고

클릭을 해보면 우측에 각 속성 값들을 확인할 수 있습니다.

그럼 여기서 찾은 xpath를 이용해서 ‘1+2 =’ 의 계산과정을 해보겠습니다.

from configuration import webDriver
from appium.webdriver.common.touch_action import TouchAction
import time
wd = webDriver.cal()
# tap
# action = TouchAction(wd)
# action.press(x=700, y=700).move_to(x=700, y=1400).release().perform()
# for i in range(7, 17):
# wd.press_keycode(i)
wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”1″]’).click() wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”더하기”]’).click() wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”2″]’).click() wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”계산”]’).click()

우리는 계산기 앱을 열어서 1+2 라는 계산과정을 해봤습니다.

이제 엑셀에 저장되있는 테스트 데이터를 python으로 불러와서 appium 서버를 통해 계산기앱을 테스트 해보도록 하겠습니다.

엑셀파일의 데이터는 아래와 같이 구성하도록 하겠습니다.

A열에는 case의 번호를 입력하고

B열에는 첫번째 숫자 / C열에는 어떤 연산을 할 건지 /D열에는 C열의 연산자의 설명 (계산기 앱에서 연산자를 구별할 때 필요)

E열에는 두번째 숫자 / F열에는 두 숫자를 연산한 결과를 입력 했습니다.

엑셀파일은 testData 란 폴더를 만들고 그 하위에 놓겠습니다.
자 그럼 pycharm으로 돌아와서 4편에서 만들었던 test_1 파일을 복사/붙여넣기 해서 test_2.py 파일을 만들어 줍니다.
불필요한 부분은 지워주고 현재는 이 줄만 있으면 됩니다.
from configuration import webDriver
wd = webDriver.cal()

데이터 불러오기

자 그럼 이제 엑셀 파일에서 데이터를 불러와야 겠죠?

이 부분은 이전에 활용했던 걸 가져와서 그래도 사용하겠습니다.

utilities라는 python package를 만들고 excelUtil.py 파일을 만들어서 아래 코드를 복사해넣습니다.

import openpyxl

# 엑셀 파일의 행수를 계산해서 반환해줌

def getRowCount(file, sheetName):

workbook = openpyxl.load_workbook(file)

sheet = workbook[sheetName]

  return sheet.max_row

# 엑셀 파일의 열 수를 계산해서 반환해줌

def getColumnCount(file, sheetName):

workbook = openpyxl.load_workbook(file)

sheet = workbook[sheetName]

  return sheet.max_column

# 엑셀 파일의 행번호, 열번호에 있는 데이터 값을 반환해줌

def readData(file, sheetName, rowNum, columnNum):

workbook = openpyxl.load_workbook(file)

sheet = workbook[sheetName]

  return sheet.cell(row=rowNum, column=columnNum).value

# data 값을 행번호, 열번호에 쓰고 파일을 저장함

def writeData(file, sheetName, rowNum, columnNum, data):

workbook = openpyxl.load_workbook(file)

sheet = workbook[sheetName] sheet.cell(row=rowNum, column=columnNum).value = data

workbook.save(file)

 

다시 test_2.py 파일로 돌아와서

사용할 엑셀 유틸을 추가해줍니다.

이제 엑셀의 데이터를 불러와서 프린트 해보겠습니다.

– 2행의 B열 값(2행, 2열)과 2행의 E열 값(2행, 5열)을 2행의 D열의 값(2행 3열)

webdriver 부분은 주석 처리 해놓겠습니다

from configuration import webDriver

from utilities import excelUtil

file_path = “..\\testData\\data.xlsx”

# wd = webDriver.cal()

first = excelUtil.readData(file_path,‘Sheet1’, 2, 2)

second = excelUtil.readData(file_path,‘Sheet1’, 2, 5)

op = excelUtil.readData(file_path,‘Sheet1’, 2, 3)

print(first, op, second)

값이 잘 불러져왔습니다.

앱 동작 만들기

이 값을 가지고 4편에서 사용했던 계산기 버튼 누르는 action에 대입해보겠습니다.

대입 하는 방법은f-string을 이용하면 됩니다.

f-string을 사용하면 문자열에 변수를 쉽게 넣을 수 있습니다.

사용법은 ” 앞에 f를 붙여주고 변수를 넣어줄 부분에 중괄호 ( { } )을 사용하면 됩니다.

아래 코드를 참고하세요

그럼 이제 변수로 계산기 앱에 연산을 하는 동작을 만들어보겠습니다.

단, 아까 연산자 부분은 2행 D열 (‘더하기’) 를 불러오겠습니다.

왜냐하면 계산기 앱에서 연산 버튼의 설명 (content-desc)이 ‘더하기’로 되있기 때문입니다.

wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{first}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{op}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{second}”]’).click() wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”계산”]’).click()

 

이제 실행을 한번 해볼까요?

현재까지 전체 코드는 아래와 같습니다.
from configuration import webDriver

from utilities import excelUtil

file_path = “..\\testData\\data.xlsx”

wd = webDriver.cal()

first = excelUtil.readData(file_path,‘Sheet1’, 2, 2)

second = excelUtil.readData(file_path,‘Sheet1’, 2, 5)

op = excelUtil.readData(file_path,‘Sheet1’, 2, 4)

wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{first}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{op}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{second}”]’).click() wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”계산”]’).click()

결과 판정하기

결과를 판정하기 위해서 엑셀에서 결과를 불러오는 부분을 추가합니다.

result = excelUtil.readData(file_path,‘Sheet1’, 2, 6)

 

그리고 계산기 앱에서 결과를 불러와야 됩니다.

계산기 앱의 결과 값 나오는 부분의 ID는 ‘com.sec.android.app.popupcalculator:id/calc_edt_formula’ 입니다.

그래서 이 부분은 ‘find_element_by_id’ 로 찾아줘야 합니다. 그리고 element에서 text만 추출하고(.text) 이걸 다시 실수화(float())를 해줘야 합니다.

아래와 같은 코드가 됩니다.

cal_result = float(wd.find_element_by_id(‘com.sec.android.app.popupcalculator:id/calc_edt_formula’).text)


마지막으로 result 와 cal_result가 같은지를 가지고 판정을 하는 판단문을 넣어줍니다.

if result == cal_result:

print(“TEST1 : PASS”)

전체코드는 아래와 같습니다.

from configuration import webDriver

from utilities import excelUtil

file_path = “..\\testData\\data.xlsx”

wd = webDriver.cal()

first = excelUtil.readData(file_path,‘Sheet1’, 2, 2)

second = excelUtil.readData(file_path,‘Sheet1’, 2, 5)

op = excelUtil.readData(file_path,‘Sheet1’, 2, 4)

result = excelUtil.readData(file_path,‘Sheet1’, 2, 6)

wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{first}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{op}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{second}”]’).click() wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”계산”]’).click()

cal_result = float(wd.find_element_by_id(‘com.sec.android.app.popupcalculator:id/calc_edt_formula’).text)

if result == cal_result:

print(“TEST1 : PASS”)

결과를 보면 아래와 같이 나옵니다.

Test DATA 갯수만큼 반복하기

이제 마지막 단락 입니다.

우리는 테스트를 한개만 할게 아니니까 Test Data 갯수만큼 반복을 해줘야 합니다.

반복을 몇 번해야 되는지는 행 개수로 판단을 하면 됩니다.

N = excelUtil.getRowCount(file_path, ‘Sheet1’)


그럼 반복문으로 바꿔 보겠습니다.

2부터 N+1까지 반복하는 for문을 만들고

2행 부분을 모두 i로 변경해줍니다.

마지막 판단문에서 f-string을 이용해서 Test 번호를 지정해줍니다. (-1을 넣어주는 이유는 아시겠죠? 2행부터니까..)

for i in range(2, N+1):

first = excelUtil.readData(file_path,‘Sheet1’, i, 2)

second = excelUtil.readData(file_path,‘Sheet1’, i, 5)

op = excelUtil.readData(file_path,‘Sheet1’, i, 4)

result = excelUtil.readData(file_path,‘Sheet1’, i, 6)

wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{first}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{op}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{second}”]’).click() wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”계산”]’).click()

cal_result = float(wd.find_element_by_id(‘com.sec.android.app.popupcalculator:id/calc_edt_formula’).text)

if result == cal_result:

print(f“TEST{i-1} : PASS”)

 

실행을 해보겠습니다.

전체 코드는 아래와 같습니다.

from configuration import webDriver

from utilities import excelUtil

file_path = “..\\testData\\data.xlsx”

N = excelUtil.getRowCount(file_path, ‘Sheet1’)

wd = webDriver.cal()

for i in range(2, N+1):

first = excelUtil.readData(file_path,‘Sheet1’, i, 2)

second = excelUtil.readData(file_path,‘Sheet1’, i, 5)

op = excelUtil.readData(file_path,‘Sheet1’, i, 4)

result = excelUtil.readData(file_path,‘Sheet1’, i, 6)

wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{first}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{op}”]’).click() wd.find_element_by_xpath(f‘//android.widget.Button[@content-desc=”{second}”]’).click() wd.find_element_by_xpath(‘//android.widget.Button[@content-desc=”계산”]’).click()

cal_result = float(wd.find_element_by_id(‘com.sec.android.app.popupcalculator:id/calc_edt_formula’).text)

if result == cal_result:

print(f“TEST{i-1} : PASS”)

 

콘솔에서 출력되는 결과는 아래와 같습니다.

결과가 정상적으로 출력 되었습니다.