본문 바로가기
테스팅 자동화

UI Automator Viewer를 이용하여 Element의 정보 확인하기

by 양초털이범 2021. 10. 10.

UI Automator Viewer


 

https://candletheif.tistory.com/37

 

Appium을 통한 자동화 테스팅 준비 - 환경 설정 및 실행

환경 설정 및 실행 https://candletheif.tistory.com/36 Appium을 통한 자동화 테스팅 준비 - 환경 설치 자동화 테스팅 테스팅은 제품의 품질과 요구사항 만족을 위해 꼭 필요한 과정입니다. 많은 시간을 들

candletheif.tistory.com

 

지난번 게시글에서 Appium을 이용하여 환경 설정 및 실행을 진행하였습니다.

 

오늘은 UI Automator Viewer를 이용하여 Element의 정보를 확인하고 탭해보는 방법을 알아보겠습니다.

 

UI Automator Viwer 위치

 

위 링크의 게시글에서 설명해드린 대로 안드로이드 스튜디오를 설치하셨다면 UI Automator Viwer도 같이 설치되었을 겁니다. 

 

자기가 설치한 경로마다 다르지만 대부분 C:\Users\USER\AppData\Local\Android\Sdk\tools\bin에 위치해 있을 것입니다.

 

UI Automator Viwer 실행

UI Automator Viwer를 실행했다면 다음과 같이 프로그램이 실행됩니다. 

 

왼쪽 상단 두 번째에 위치한 Device Screenshot 버튼을 탭하면 PC에 연결한 디바이스의 화면을 캡처하여 Elememt의 정보들을 얻을 수 있습니다.

 

지난번 환경 테스트에서 설치한 구글의 계산기 앱을 통해 Elememt의 정보 얻는 방법을 확인해보겠습니다.

 

앱 실행 후 Device Screenshot를 사용하여 캡쳐한 모습 

계산기 앱을 실행하고 Device Screenshot 버튼을 탭하면 다음과 같은 모습을 확인할 수 있습니다.

①디바이스 캡처 화면 : 현재 실행 중인 앱의 화면입니다. 마우스를 가져다 Elememt에 올려두면 오른쪽에서 정보를 확인할 수 있습니다.
②그룹 및 Element의 좌표 : 선택한 Elememt가 속한 그룹과 좌표를 확인할 수 있습니다.
③선택한 Element의 정보 : 선택한 Elememt의 정보를 확인할 수 있습니다. 

 

위의 정보를 활용하여 Elememt를 찾고 탭하는 코드를 작성해보겠습니다.

 

xpath


xpath를 이용하면 더욱 정확하게 Elememt를 찾아낼 수 있습니다.

xpath를 이용하는 코드는 다음과 같습니다.

 

driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

driver.findElementByXPath("//class['정보']").click();

 

 

코드만으로는 감이 오지 않을 테니 직접 실행해보겠습니다.

 

5버튼의 class 확인

5 버튼을 탭하면 class가 android.widget.Button인 것을 알 수 있습니다.

 

이를 통하여 코드를 작성해보면

 

driver.findElementByXPath("android.widget.Button['정보']").click;

가 됩니다.

 

 

[] 안에 들어간 '정보'는 다양한 값들을 넣을 수 있는데 index, text, resource-id, content-desc 등이 있습니다.

UI Automator Viwer의 정보를 이용하여 5를 누르는 코드를 작성해보면

 

//text를 이용하여 5를 입력
driver.findElementByXPath("//android.widget.Button[@text='5']").click();

//resource-id를 이용하여 5를 입력(contains을 사용하여 /뒤에 있는 digit_5만 입력해줍니다)
driver.findElementByXPath("//android.widget.Button[contains(@resource-id, 'digit_5')]").click();

//index를 이용하여 5를 입력
driver.findElementByXPath("//android.widget.Button[@index='4']").click();

가 됩니다.

 

해당 코드를 실행하면 다음과 같이 실행됩니다.

 

 

영상을 확인해보시면 마지막에 5가 아닌 tan을 탭하는 모습을 볼 수 있습니다.

분명히 5의 정보인 index = 4를 입력했는데 왜 tan 눌리는 걸까요?

 

이유는 tan의 index도 4이기 때문입니다.

tan의 index

appium에서 실행하는 자동화는 같은 값이 있을 때 최상단에 있는 값을 먼저 찾아냅니다.

tan의 index도 4, 5의 index도 4이지만 5보다 위에 있는 tan을 찾아 탭하는 것이지요.

이를 방지하기 위해선 and를 사용하여 복합적인 정보를 입력하면 됩니다.

 

//index와 text를 이용하여 5를 입력
driver.findElementByXPath("//android.widget.Button[@index='4' and @text=5]").click();

//index와 resoureced-id를 이용하여 5를 입력
driver.findElementByXPath("//android.widget.Button[@index='4' and contains(@resource-id, 'digit_5')]").click();

 

해당 코드를 실행하면 다음과 같이 실행됩니다.

 

index를 사용하였지만 tan이 아닌 5를 탭합니다.

 

좌표


xpath에 정보가 없거나 동일한 정보를 가지고 있는 경우 좌표를 이용해서 탭할 수 있습니다.

 

하지만 좌표를 사용하는 것은 추천해드리지 않습니다. 기기마다 좌표가 다르고, 외부 사정이나 팝업창으로 인해 오류 발생률이 높아지니 어쩔 수 없는 경우에만 사용하시길 바랍니다.

 

좌표를 이용하는 코드는 다음과 같습니다.

driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

new TouchAction(driver).tap(PointOption.point(x, y)).perform();

 

코드만으로는 감이 오지 않을 테니 직접 실행해보겠습니다.

코드에 좌표를 입력하여 직접 실행해보겠습니다.

5의 좌표

오른쪽 상단에서 5의 좌표를 확인할 수 있습니다. 해당 좌표를 탭하는 코드는 다음과 같습니다.

 

new TouchAction(driver).tap(PointOption.point(248, 1549)).perform();

 

해당 코드를 실행하면 다음과 같이 실행됩니다.

 

 

5를 탭하는 모습을 볼 수 있습니다. 영상에서 보신 것처럼 좌표를 입력하여 탭하는 방식은 빠르게 이루어지니 사이에 Thread.sleep(s);를 사용하여 간격을 두는 걸 추천드립니다.

 

반대로 xpath를 통해 Element의 좌표를 읽어와 좌표 값을 탭할 수 있습니다. 코드는 다음과 같습니다.

//getLocation()을 이용하여 xpath의 point를 저장
Point point = driver.findElementByXPath("//android.widget.Button[@text='5']").getLocation();

new TouchAction(driver).tap(PointOption.point(point)).perform();

 

종합


위에서 배운 내용을 바탕으로 계산을 수행해보도록 하겠습니다.

 

12*87을 수행하여 올바른 값인 1044를 출력하는지 확인하는 테스트

package test;

import java.net.URL;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.Point;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;

import io.appium.java_client.touch.LongPressOptions;
import io.appium.java_client.touch.offset.PointOption;

public class at {
	public static AppiumDriver<AndroidElement> driver;
	public static DesiredCapabilities capabilities = new DesiredCapabilities();
	
	@BeforeClass
	public void setUp() throws Exception {
		capabilities.setCapability("appPackage", "com.google.android.calculator");
		capabilities.setCapability("appActivity", "com.android.calculator2.Calculator");
		capabilities.setCapability("deviceName", "device");
		capabilities.setCapability("udid", "단말기의 UDID 번호 입력");
		capabilities.setCapability("unicodeKeyboard", "true");
		capabilities.setCapability("resetKeyboard", "true");
	
		driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
	}
	
	@Test
	public void Test1() throws Exception {
		//text를 이용하여 1을 탭
		driver.findElementByXPath("//android.widget.Button[@text='1']").click();

		//resource-id를 이용하여 2를 탭(contains을 사용하여 /뒤에 있는 digit_2만 입력해줍니다)
		driver.findElementByXPath("//android.widget.Button[contains(@resource-id, 'digit_2')]").click();
		
		//index와 resoureced-id를 이용하여 x를 탭
		driver.findElementByXPath("//android.widget.Button[@index='2' and @content-desc='×']").click();
		
		//좌표를 지정하여 8을 탭 (좌표값을 탭하기 전에 2초의 여유 시간을 준다)
		Thread.sleep(2000);
		new TouchAction(driver).tap(PointOption.point(248, 1312)).perform();
		
		//getLocation()을 이용하여 xpath의 point를 저장 후 7탭
		Thread.sleep(2000);
		Point point = driver.findElementByXPath("//android.widget.Button[@text='7']").getLocation();
		new TouchAction(driver).tap(PointOption.point(point)).perform();
		
		//content-desc를 이용하여 = 탭
		driver.findElementByXPath("//android.widget.Button[@content-desc='등호']").click();
		
		//올바른 결과 값이 나오는지 확인 최종 결과 값을 저장하는 result_final의 text를 저장 후 올바른 결과와 비교한다.
		String result = driver.findElementByXPath("//android.widget.TextView[contains(@resource-id, 'result_final')]").getText();
		Assert.assertEquals(result, "1044");
		
		Thread.sleep(5000);
	}
	
	@AfterClass
	public void end() throws Exception {
		driver.quit();
	}
}

해당 코드를 실행하면 다음과 같이 실행됩니다.

 

 

 

마무리


오늘은 UI Automator Viewer를 이용하여 Element의 정보를 이용하여 탭하는 코드를 작성했습니다.

간단하지만 자주 사용하지 않으면 쉽게 잊어버리니 자주 사용하는 문법을 적어두시면 좋을 것입니다.

 

댓글