don't stop believing

Selenium Grid를 이용한 appium 멀티 실행 본문

Testing Automation/Appium

Selenium Grid를 이용한 appium 멀티 실행

Tongchun 2017. 11. 30. 17:35

테스트 자동화 대상은 4개의 디바이스에서 실행되어야 합니다.

  • Android Native App
  • iOS Native App
  • Android Unity App
  • iOS Unity App

동시에 위 4개의 테스트를 동시에 진행하고 싶습니다.

appium을 이용해 어려대의 디바이스를 동시에 실행해 테스트하기 위해서는 Selenium Grid를 이용합니다.

Selenium Server가 각 device별로 설정된 4개의 Appium 서버를 연결해 주는 방식입니다.


Selenium Grid는 Selenium Standalone Server를 이용하며 Selenium 사이트에서 다운받을 수 있습니다.

현재는 3.7.1버전이네요. selenium-server-standalone-3.7.1.jar 파일을 다운받습니다.

[http://www.seleniumhq.org/download/]

jar이기 때문에 java가 설치되어 있어야 합니다.


다운받은 selenium 서버를 실행시켜 봅시다. terminal로 다운받은 경로로 이동해 아래와 같이 실행시킵니다.

$ java -jar selenium-server-standalone-3.7.1.jar -role hub

그리고 브라우저를 열어 아래 rul을 호출해 봅니다.

http://127.0.0.1:4444/grid/console


아직 등록된 node가 없어서 아래 화면을 보게 됩니다.

이제 4개의 node를 만들어 줍니다.

각 node에 대한 Configuration을 json파일로 작성해 줍니다.


grid-native-and-v10.json

{
	"capabilities": [{
		"deviceName": "V10",
		"version": "6.0",
		"maxInstances": 3,
		"platform": "ANDROID",
		"udid": "LGF600Kb1134738"
	}],
	"configuration": {
		"cleanUpCycle": 2000,
		"timeout": 30000,
		"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
		"url": "http://127.0.0.1:4721/wd/hub",
		"host": "127.0.0.1",
		"port": 4721,
		"maxSession": 6,
		"register": true,
		"registerCycle": 5000,
		"hub": "http://127.0.0.1:4444/grid/register/",
		"hubPort": 4444,
		"hubHost": "127.0.0.1",
		"remoteHost": "http://127.0.0.1:4721",
		"role": "node"
	}
}


grid-native-ios-6.json

{
	"capabilities": [{
		"deviceName": "iPhone-6",
		"version": "11.0",
		"maxInstances": 3,
		"platform": "iOS",
		"udid": "73439839ee3db7b59fcdd8bc3aa8cc4862006b7b"
	}],
	"configuration": {
		"cleanUpCycle": 2000,
		"timeout": 30000,
		"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
		"url": "http://127.0.0.1:4722/wd/hub",
		"host": "127.0.0.1",
		"port": 4722,
		"maxSession": 6,
		"register": true,
		"registerCycle": 5000,
		"hub": "http://127.0.0.1:4444/grid/register/",
		"hubPort": 4444,
		"hubHost": "127.0.0.1",
		"remoteHost": "http://127.0.0.1:4722",
		"role": "node"
	}
}


grid-unity-and-note5.json

{
	"capabilities": [{
		"deviceName": "Note5",
		"version": "5.1",
		"maxInstances": 3,
		"platform": "ANDROID",
		"udid": "0715f7ca177b2936"
	}],
	"configuration": {
		"cleanUpCycle": 2000,
		"timeout": 30000,
		"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
		"url": "http://127.0.0.1:4723/wd/hub",
		"host": "127.0.0.1",
		"port": 4723,
		"maxSession": 6,
		"register": true,
		"registerCycle": 5000,
		"hub": "http://127.0.0.1:4444/grid/register/",
		"hubPort": 4444,
		"hubHost": "127.0.0.1",
		"remoteHost": "http://127.0.0.1:4723",
		"role": "node"
	}
}


grid-unity-ios-6s.json

{
	"capabilities": [{
		"deviceName": "iPhone-6S",
		"version": "10.0",
		"maxInstances": 3,
		"platform": "iOS",
		"udid": "1b0fa7ad922b08b79c2adf4f841ec407a8cedd64"
	}],
	"configuration": {
		"cleanUpCycle": 2000,
		"timeout": 30000,
		"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
		"url": "http://127.0.0.1:4724/wd/hub",
		"host": "127.0.0.1",
		"port": 4724,
		"maxSession": 6,
		"register": true,
		"registerCycle": 5000,
		"hub": "http://127.0.0.1:4444/grid/register/",
		"hubPort": 4444,
		"hubHost": "127.0.0.1",
		"remoteHost": "http://127.0.0.1:4724",
		"role": "node"
	}
}


android 디바이스의 udid는 adb devices로 확인해 기입합니다.

$ adb devices
List of devices attached
LGF600Kb1134738	device
0715f7ca177b2936	device

configuration 정보 중 url, host, post는 Appium Server 정보이며 Port는 4721부터 순차적으로 적어줍니다.

hub, hubPort, hubHost 정보는 Selenium Server 정보를 기입해 줍니다.


이제 json파일을 이용해 4개의 appium 서버를 실행합니다. 실행 옵션은 아래와 같습니다.


Native Android V10

appium \
	--nodeconfig grid-native-and-v10.json \
	--port 4721 \
	--command-timeout 7200 \
	--app ./appfiles/KakaoGameSDK_Test_App_3.5.1.148.apk \
	--device-name V10 \
	--udid LGF600Kb1134738 \
	--tmp /Users/tongchunkim/Documents/TestAppium/temp/v10/


Native iOS 6

(참고로 저는 iOS 앱을 TestFlight로 관리합니다. 따라서 Appium Server를 실해할 때 --app 옵션을 제외합니다.)

appium \
	--nodeconfig grid-native-ios-6.json \
	--port 4722 \
	--command-timeout 7200 \
	--app ./appfiles/com.kakaogames.sdk.sample.ipa \
	--device-name iPhone-6 \
	--udid  73439839ee3db7b59fcdd8bc3aa8cc4862006b7b \
	--tmp /Users/tongchunkim/Documents/TestAppium/temp/iphone6/


Unity Android Note5

appium \
	--nodeconfig grid-unity-and-note5.json \
	--port 4723 \
	--command-timeout 7200 \
	--app ./appfiles/UnityTestAndroid.apk \
	--device-name Note5 \
	--udid 0715f7ca177b2936 \
	--tmp /Users/tongchunkim/Documents/TestAppium/temp/note5/


Unity iOS 6S

(참고로 저는 iOS 앱을 TestFlight로 관리합니다. 따라서 Appium Server를 실해할 때 --app 옵션을 제외합니다.)

appium \
	--nodeconfig grid-unity-ios-6s.json \
	--port 4724 \
	--command-timeout 7200 \
	--app ./appfiles/com.kakaogames.sdk.unitysample.ipa \
	--device-name iPhone-6S \
	--udid  1b0fa7ad922b08b79c2adf4f841ec407a8cedd64 \
	--tmp /Users/tongchunkim/Documents/TestAppium/temp/iphone6S/

먼저 Selenium 서버가 실행되어 있는지 확인하고 위 4개의 Appium 서버를 순차적으로 실행합니다.

그럼 아래와 같이 Selenium 서버에 4개의 Appium 서버가 연결된 것을 확인할 수 있습니다.

17:59:36.434 INFO - Nodes should register to http://169.254.173.156:4444/grid/register/
17:59:36.435 INFO - Selenium Grid hub is up and running
17:59:55.126 INFO - Registered a node http://127.0.0.1:4721
18:00:00.180 INFO - Registered a node http://127.0.0.1:4722
18:00:04.659 INFO - Registered a node http://127.0.0.1:4723
18:00:08.878 INFO - Registered a node http://127.0.0.1:4724

브라우저를 열고 selenium 서버를 호출하면 4개의 node(Appium Server)가 연결된 것을 확인 할 수 있습니다.

http://127.0.0.1:4444/grid/console

이제 Appium Client로 각 Appium Server로 연결해 봅시다.

각 Client의 SetUp Method들은 아래와 같습니다.


Native Android V10

def setUp(self):
    desired_caps = {}
    desired_caps['platformName'] = 'ANDROID'
    desired_caps['platformVersion'] = '6.0'
    desired_caps['deviceName'] = 'V10'
    desired_caps['newCommandTimeout'] = 7200
    desired_caps['automationName'] = 'Appium'
    desired_caps['app'] = os.path.abspath(os.path.join(os.path.dirname(__file__), '/Users/tongchunkim/Documents/TestAppium/appfiles/', 'KakaoGameSDK_Test_App_3.5.1.148.apk'))
    desired_caps['appPackage'] = 'com.kakaogame.sample'
    desired_caps['appActivity'] = 'com.kakaogame.sample.SampleActivity'
    desired_caps['noReset'] = False

    self.driver = webdriver.Remote('http://127.0.0.1:4721/wd/hub', desired_caps)



Native iOS 6

def setUp(self):
    desired_caps = {}
    desired_caps['platformName'] = 'iOS'
    desired_caps['platformVersion'] = '11.0'
    desired_caps['deviceName'] = 'iPhone-6'
    desired_caps['automationName'] = 'XCUITest'
    desired_caps['newCommandTimeout'] = 7200
    desired_caps['bundleId'] = 'com.kakaogames.sdk.sample'
    desired_caps['udid'] = '73439839ee3db7b59fcdd8bc3aa8cc4862006b7b'
    desired_caps['xcodeOrgId'] = 'WVC7779982'
    desired_caps['xcodeSigningId'] = 'iPhone Developer'
    desired_caps['noReset'] = False

    self.driver = webdriver.Remote('http://127.0.0.1:4722/wd/hub', desired_caps)


Unity Android Note5

def setUp(self):
    desired_caps = {}
    desired_caps['platformName'] = 'ANDROID'
    desired_caps['platformVersion'] = '5.1'
    desired_caps['deviceName'] = 'Note5'
    desired_caps['newCommandTimeout'] = 7200
    desired_caps['automationName'] = 'Appium'
    desired_caps['app'] = os.path.abspath(os.path.join(os.path.dirname(__file__), '/Users/tongchunkim/Documents/TestAppium/appfiles/', 'UnityTestAndroid.apk'))
    desired_caps['appPackage'] = 'com.kakaogames.sdk.unitysample'
    desired_caps['noReset'] = False

    self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)



Unity iOS 6S

def setUp(self):
    desired_caps = {}
    desired_caps['platformName'] = 'iOS'
    desired_caps['platformVersion'] = '10.0'
    desired_caps['deviceName'] = 'iPhone-6S'
    desired_caps['automationName'] = 'XCUITest'
    desired_caps['newCommandTimeout'] = 7200
    desired_caps['bundleId'] = 'com.kakaogames.sdk.unitysample'
    desired_caps['udid'] = '1b0fa7ad922b08b79c2adf4f841ec407a8cedd64'
    desired_caps['xcodeOrgId'] = 'WVC7779982'
    desired_caps['xcodeSigningId'] = 'iPhone Developer'
    desired_caps['noReset'] = False

    self.driver = webdriver.Remote('http://127.0.0.1:4724/wd/hub', desired_caps)

이제 4개의 Device에서 동시에 테스트할 수 있습니다.



Comments