Maestro Flakiness: 소스 코드 분석

발행: (2025년 12월 25일 오후 04:36 GMT+9)
6 분 소요
원문: Dev.to

Source: Dev.to

Cover image for Maestro Flakiness: Source Code Analysis

Om Narayan

Maestro는 모바일 애플리케이션의 불안정성을 “수용한다”는 테스트 프레임워크로 자신을 홍보합니다.
하지만 실제 코드에서는 이것이 정확히 무엇을 의미할까요? 저는 소스를 직접 파헤쳐 보았습니다.

마케팅 약속

Maestro 문서에서:

“UI 요소가 항상 예상한 위치에 있지는 않으며, 화면 탭이 항상 통과하지도 않습니다. Maestro는 모바일 애플리케이션과 기기의 불안정성을 수용하고 이를 보완하려고 합니다.”
“테스트에 sleep() 호출을 여기저기 삽입할 필요가 없습니다. Maestro는 콘텐츠 로드에 시간이 걸릴 수 있음을 알고 자동으로 기다려 주지만(필요 이상으로 오래 기다리지는 않습니다).”

멋지게 들리죠. 실제 코드가 무엇을 하는지 살펴봅시다.

Source: Orchestra.kt

1. Element Finding – 하드코딩된 17초 타임아웃

tapOn: "Login"을 작성하면 Maestro는 한 번 보고 실패하지 않습니다. 지속적으로 폴링합니다. 하지만 얼마나 오래 폴링할까요?

class Orchestra(
    private val maestro: Maestro,
    private val lookupTimeoutMs: Long = 17000L,        // Hardcoded: 17 seconds
    private val optionalLookupTimeoutMs: Long = 7000L // Hardcoded: 7 seconds for optional
)

이것이 의미하는 바

  • 모든 요소 조회는 기본적으로 17초까지 대기합니다.
  • 선택적 요소는 7초까지 대기합니다.
  • 이 값을 명령마다 변경할 수 없습니다.

느린 API 응답 때문에 30초를 기다리고 싶나요? 안 됩니다. 성능 테스트를 위해 3초 안에 빠르게 실패시키고 싶나요? 역시 불가능합니다.

2. 폴링 메커니즘 – 간단하지만 경직됨

Source: MaestroTimer.kt

fun  withTimeout(timeoutMs: Long, block: () -> T?): T? {
    val endTime = System.currentTimeMillis() + timeoutMs

    do {
        val result = block()
        if (result != null) {
            return result
        }
    } while (System.currentTimeMillis()

Note: 최대 대기 시간은 10초(10회 폴링 × 1초)입니다. 이 값은 구성할 수 없습니다.

7. 플랫폼 차이점: Android vs iOS

Maestro는 플랫폼마다 “settling”(정착) 방식을 다르게 처리합니다.

Android

Source: AndroidDriver.kt

// Checks if window is still updating
val windowUpdating = blockingStubWithTimeout.isWindowUpdating(...)

iOS

Source: IOSDriver.kt

// Uses screenshot comparison to detect animation end
val didFinishOnTime = waitUntilScreenIsStatic(SCREEN_SETTLE_TIMEOUT_MS)

두 접근 방식은 신뢰성 특성이 다르지만, 구성 가능성을 제공하지 않습니다.

요약: 하드‑코딩된 현실

매개변수구성 가능?
요소 조회 제한시간17,000 ms❌ 아니오
선택적 요소 제한시간7,000 ms❌ 아니오
탭 재시도 시도 횟수2❌ 아니오
최대 재시도 명령3❌ 아니오
스크린샷 차이 임계값0.5 %❌ 아니오
정착 폴링 간격200 ms❌ 아니오
정착 최대 반복 횟수10❌ 아니오
waitUntilVisible 제한시간10,000 ms❌ 아니오

평결

Maestro의 “내장 플라키니스 처리”는 순수 XCUITest나 Espresso보다 더 많은 일을 하지만, 하드코딩된 값이 있는 일괄 해결책이다.

  • 코드가 깔끔하고 접근 방식이 타당하다.
  • 탈출구가 없다는 것은 기본값이 앱에 맞지 않을 때 해결책이 없다는 뜻이다.

이는 반드시 나쁜 것은 아니며—단순함을 위한 트레이드오프이다. 그러나 마케팅은 실제 코드가 제공하는 것보다 더 높은 지능과 적응성을 암시한다.

주요 소스 파일

FileDescription
Orchestra.kt명령 실행 및 타임아웃
Maestro.kt탭 로직 및 재시도
MaestroTimer.kt폴링 기본 기능
ScreenshotUtils.kt스크린샷 비교
Commands.kt명령 정의

우리는 단순히 문제를 지적하는 것이 아닙니다

우리는 Maestro의 YAML 구문을 사랑합니다—수년간 모바일 테스트 자동화에 일어난 최고의 변화라고 할 수 있습니다: 간단하고, 가독성이 좋으며, 버전‑컨트롤에 친화적입니다.

하지만 실행 엔진에는 실제 제한 사항이 있습니다:

  • 고정된 타임아웃
  • 구성 가능성 없음
  • 플랫폼 간 불일치

그래서 우리는 이를 해결하기 위해 무언가를 만들고 있습니다.

Appium의 검증된 인프라 위에서 Maestro YAML 테스트를 실행하는 오픈‑소스 엔진으로, 다음을 제공합니다:

  • 설정 가능한 타임아웃
  • 실제 디바이스 지원
  • 매직 넘버 없음

이곳을 주목해 주세요.

Learn More

Back to Blog

관련 글

더 보기 »