모바일 자동화테스트에서는 드라이버의 생성 전략에 대해 별도로 고민해보긴 해야합니다.
회사에서 자동화에 대해 고민중이라면, 무조건 로컬, 자신의 컴퓨터에서만 돌릴 의도는 없으므로 로컬과 리모트를 신경써야하고, 안드로이드와 iOS, 그리고 에뮬레이터와 실기기를 따져봐야합니다.
지금 당장 떠오르는 것은 pytest의 addoption
기능을 통해, 커맨드라인 명령어 옵션에 커스텀 옵션을 추가한다음 이것을 분기처리하는 것입니다.
이렇게 하면 당장 로컬에서 실행할 때는 물론, 로컬에서 리모트를 실행시키거나, 젠킨스 등에서 노드의 기기를 실행시킬때에도 유연하게 할 수 있을 것 입니다.
def pytest_addoption(parser):
## local, remote
parser.addoption(
"--env", action="store", default="local"
)
## aos, ios
parser.addoption(
"--os", action="store", default="aos"
)
## emulator, real
parser.addoption(
"--device", action="store", default="emulator"
)
@fixture(autouse=True)
def setup_and_teardown(request) -> webdriver.Remote:
os_name = request.config.getoption("os")
execute_env = request.config.getoption("env")
device_type = request.config.getoption("device")
driver: webdriver.Remote
if execute_env == "local":
if os_name == "aos" and device_type == "emulator":
driver = DriverSetup.local_android_driver(device_name="emulator-5554",
app_path="/Users/~~~ test.apk")
if os_name == "aos" and device_type == "real":
driver = DriverSetup.local_android_driver(device_name="dsdsddsd")
## TODO
if os_name == "ios" and device_type == "emulator":
pass
if os_name == "ios" and device_type == "real":
driver = DriverSetup.local_ios_driver(device_name="iPhone 11 (iOS 15.0.2)",
udid="~~~~")
else:
pass
request.cls.driver = driver
driver.implicitly_wait(10)
request.cls.driver = driver
yield
request.cls.driver.quit()
여기서 관리문제가 발생하게 되는데, 로컬의 경우에는 각자 작업자가 가진 에뮬레이터 정보나, 단말기의 정보가 각각 달라서 코드 안에 하드코딩할 수가 없습니다. (협업 시에 문제가 발생하게됨)
그래서 .ini
파일을 하나 만든 다음에, .gitignore
에 등록해서 커밋되지 않게 해봅니다.
즉 이 파일은 작업자들이 각자 만들어서 각각 관리하는 것입니다.
[LOCAL_DEVICE]
android_emulator_name = emulator-5554
android_app_path = /Users/~~~android.apk
android_real_device_name = ~~~
ios_real_device_name = iPhone 11 (iOS 15.0.2)
ios_real_device_udid = ~~~~
import configparser
def get_config(ini_file_path:str = None) -> configparser.ConfigParser:
config_reader = configparser.ConfigParser()
if ini_file_path is None:
config_reader.read("./resources/local_device_info.ini")
else:
config_reader.read(ini_file_path)
return config_reader
@fixture(autouse=True)
def setup_and_teardown(request) -> webdriver.Remote:
os_name = request.config.getoption("os")
execute_env = request.config.getoption("env")
device_type = request.config.getoption("device")
driver: webdriver.Remote
if execute_env == "local":
local_device_info = utilities.get_config()["LOCAL_DEVICE"]
if os_name == "aos" and device_type == "emulator":
driver = DriverSetup.local_android_driver(device_name=local_device_info["android_emulator_name"],
app_path=local_device_info["android_app_path"])
if os_name == "aos" and device_type == "real":
driver = DriverSetup.local_android_driver(device_name=local_device_info["android_real_device_name"])
## TODO
if os_name == "ios" and device_type == "emulator":
pass
if os_name == "ios" and device_type == "real":
driver = DriverSetup.local_ios_driver(device_name=local_device_info["ios_real_device_name"],
udid=local_device_info["ios_real_device_udid"])
else:
## remote
pass
request.cls.driver = driver
driver.implicitly_wait(10)
request.cls.driver = driver
yield
request.cls.driver.quit()
이렇게 하면 협업 시에 좀 더 여러가지 개발환경에 대하여 대응할 수 있을 것입니다.