How to find image in Mobile screen on Appium

Dahun Yoo·2023년 6월 27일
0

Appium with python

목록 보기
8/13
post-thumbnail

Appium을 이용한 단말기 조작 시에, 찾고자하는 이미지를 인식시킨 후 스크린에서 해당 이미지를 찾았을 때의 핸들링하는 방법에 대해 기재해봅니다.


Appium server plugin

Appium 2.0 이상부터는, appium 서버에서 몇몇 플러그인 기능을 지원하는데요, 그 중에서 visual 테스트 등을 위해서 image 플러그인을 제공하고 있습니다.
OpenCV 를 통해 지원하는 이 기능은, 이미지 비교가 아닌 이미지 형태의 element를 찾기 위해서는 별도로 OpenCV 라이브러리를 클라이언트에 설치할 필요는 없어보입니다.

Installation

일단 앱피움 서버 버전이 2.0이상인 상태에서, 아래 명렁어를 통해 플러그인을 설치해줍니다.

appium plugin install images

Find element by Image

이 플러그인을 설치하면 사용할 수 있는 기능 중에, 저는 findElementByImage() 를 사용하여 네이버페이 결제 자동화를 진행했고, 큰 어려움 없이 진행했습니다.

Using the -image locator strategy supported by this plugin, it is possible to send an Appium an image file representing an element you want to tap. If Appium can find a screen region matching your template, it will wrap up information about this region as a standard WebElement and send it back to your Appium client.

https://github.com/appium/appium/blob/master/packages/images-plugin/docs/find-by-image.md#finding-and-interacting-with-image-elements

위 설명에 따르면, -image 로케이터와 , 찾고자하는 템플릿 이미지를 조합하여 코드를 실행하는 단말기 화면 상에서 해당 이미지를 찾아내고, 만약 찾아내면 적당한 크기로의 element값으로 인식하여 반환한다~ 정도 인 것 같습니다.

prerequisites

준비사항으로는 일단 테스트하고자 하는 단말기에서, 테스트를 진행하면서 인식시키고자 하는 이미지에 대해 미리 스크린샷을 찍고 크롭핑을 해야합니다.
왜 하필 단말기에서 스크린샷을 찍어야하냐면, 이미지의 해상도를 확인하여 지정한 정확도에서 일치한 이미지에 대해, 해당 영역을 element로 습득하여 다룰 수 있게되기 때문입니다. (참고로 정확도를 1로 지정하면, 픽셀단위로 일치하는 지를 검증)

때문에 동작시키고자 하는 단말기에서 스크린샷을 찍어서 이미지를 준비해야 스크린샷의 해상도나 크기 등이 실제 단말기의 스크린과 일치할 확률이 높아집니다.

위와 같이 단말기에서 직접 스크린샷을 찍은 후에, 자동화하면서 찾고자하는 키패드 영역 숫자에 대해 0부터 9까지 하나씩 크롭핑하여 준비합니다.

server run

앱피움 서버를 실행시킬 때에, 미리 설치한 플러그인을 활성화해주어야합니다.

appium --use-plugins=images

execute code

다음은 코드 실행입니다.

일단 찾고자 하는, 미리 저장해놓은 이미지에 대해서 불러온 다음에, base64로 인코딩한 다음 문자화 시켜줍니다.

image encoding to base64

import base64
   
    
with open("YOUR\PROJECT\DIRECTORY\OR\FILE_DRECTORY\FINE_NAME.png", "rb") as image_file:
    image_base64 = base64.b64encode(image_file.read()).decode("utf-8")

find element by image and click

그 다음은 AppiumBy.IMAGE 셀렉터를 통해, 인코딩한 값과 함께 넘겨줍니다.

element = driver.find_element(AppiumBy.IMAGE, image_base64)

그 후에 element를 찾았다면 바로 원하는 동작을 해주면됩니다. 키패드를 누르는 동작을 취해야하므로,click() 을 수행해주면 될 것 입니다.

element.click()

update_settings

단, Appium 공식 문서에 따르면, 이미지 매칭의 정확도는 기본 40%(0.4) 라서, 엉뚱한 이미지를 클릭할 수도 있습니다. 따라서 일단 처음에는 높은 정확도를 설정하되, 분명히 찾고자하는 이미지가 스크린 내에 존재함에도 불구하고

  • 해당 이미지를 찾지 못하거나,
  • 이미지를 찾아 click() 을 수행하지만 알고보니 엉뚱한 키패드 이미지를 누른다면

점진적으로 정확도를 낮추어가면서 수행해볼 수도 있을 것입니다.

정확도를 설정하는 값은 다음과 같습니다.

accurency = 0.9
driver.update_settings({"imageMatchThreshold": accurency})

while True:
	try:
		element = driver.find_element(AppiumBy.IMAGE, image_base64)
        element.click()
        break # 이미지를 찾으면 클릭 후에 무한 반복문 종료

	except NoSuchElementException: #이미지를 찾지못하면 NoSuchElementException이 발생하는데 이것을 catch
    	accurency -= 0.05 # 찾고자하는 이미지와, 스크린 상에서의 이미지의 정확도(매칭률)을 조정하고
        driver.update_settings({"imageMatchThreshold": accurency}) # 정확도 업데이트 후 다시 반복 시작
        

update_settings 값에 대해서는 추가로 좀 더 설정해줄 수 있는 값들이 있으니, 자세한 것은 공식문서를 참고해보시길 바랍니다.

PC에서 selenium을 이용할 때는 pyautogui 라이브러리를 통해서 자동화를 해볼 수 있을 것 같은데요, appium을 통한 모바일에서는 해당 라이브러리를 사용할 수 없다하여 좌절하던 찰나에
의외로 손쉽게? 문제를 해결하고 결제 자동화를 시도해볼 수 있었습니다.

ref

profile
QA Engineer

0개의 댓글