XPath를 iOS 클래스 체인으로 변환하는 작업: 컨버터 대신 Claude가 할 수 있을까?
요약
본 글은 Appium XPath 로케이터를 iOS 클래스 체인으로 변환하는 컨버터의 성능을 LLM(Claude)과 비교 분석합니다. 테스트 결과, Claude가 가장 높은 점수를 기록했지만, 여전히 전문 컨버터를 능가하지 못했습니다. 모델이 정확한 결과를 내기 위해서는 명확하고 구체적인 규칙을 포함한 프롬프트와 적절한 노력 수준 설정이 필수적임을 강조합니다.
핵심 포인트
- 컨버터는 96% 이상의 높은 정확도를 보여, LLM의 성능 기준점 역할을 합니다.
- 규칙(Rule)이 없는 상태에서는 모든 모델에서 잘못된 체인 생성이 발생했습니다.
- 최신 모델을 사용하되, 비용 대비 효율성을 고려하여 'low' 또는 'medium' 노력 수준이 권장됩니다.
요약 (TL;DR)
- 컨버터를 능가한 모델은 없었다. 가장 잘 작동한 Claude의 결과는 676개의 로케이터에 대해 컨버터가 사용할 수 있는 체인의 96.7%에 도달했지만, 그보다 앞선 적은 없었다.
- 규칙이 없으면, 모든 모델 실행에서 잘못된 체인을 생성했다. (실행당 4개에서 59개, 컨버터는 0개). 규칙을 포함한 프롬프트는 Opus 5.5와 Sonnet 5.5를 **제로(zero)**로 만들었다.
- 규칙과 함께
low또는medium노력 수준으로 최신 모델을 사용하는 것이 좋다. 몇 점의 차이를 위해medium보다 최대 4.6배 높은 비용이 발생할 수 있다. 이전 세대는 더 느렸고 실수를 더 많이 했다.
목차 (Contents)
- 테스트
- 단순 요청
- 더 높은 노력 수준이 도움이 될까?
- 이전 모델들
- 모델들이 잘못 처리한 부분
- 규칙을 포함한 프롬프트
- 내가 사용할 것
- 제한 사항 (Limits)
part 1에서 나는 Appium XPath 로케이터를 iOS 클래스 체인으로 변환하는 컨버터인 xpath-to-class-chain을 만들었고, 678개의 로케이터로 테스트했다. 당연한 질문이 생겼다: 로케이터를 LLM에 붙여넣기 할 수 있다면 왜 아예 컨버터를 만들어야 하는가?
그래서 나는 Claude에게 같은 작업을 수행하도록 요청하고 동일한 검사 기준으로 답변을 점수화했다. 이것은 나 대 Claude의 싸움이 아니다: Claude Code는 내가 이 컨버터를 작성하는 데 도움을 주기도 했다. 진짜 질문은 모델이 모든 로케이터를 직접 변환하도록 내버려 두어야 하는지, 아니면 한 번 만들고 기기에서 검증한 도구를 사용해야 하는가이다.
테스트 (The test)
- 동일한 678개 로케이터: 실제 운영 테스트 스위트에서 가져온 563개의 로케이터와 수작업으로 만든 엣지 케이스 115개를 포함합니다. 총 676개가 비교되었습니다 (하나는 XPath가 아니며, 하나는 실행 시점에 다른 것을 중복합니다).
- 실행당 하나의 요청: 전체 목록을 단일 파일에 담고, 순서를 무작위로 섞었으며, 중립적인 ID를 사용하여 모델이 실제 로케이터와 엣지 케이스를 구분할 수 없게 했습니다. 모델은 각 ID에 대해 체인 또는 건너뛰기(skip)를 작성하고 그 이유를 제시합니다.
- 깨끗한 환경: 빈 폴더 내에서 Claude Code CLI를 사용하며,
읽기(Read)및쓰기(Write)도구만 사용하고 설정이나 웹 접근은 없으며, 프롬프트에는 하나의 체인 예시 외에는 없습니다. - 컨버터와 동일한 심사관: WebDriverAgent의 자체 코드로 구축된 WDA 에뮬레이터를 사용하여 생성된 수백 개의 화면에서 각 체인과 그 XPath를 실행하고 발견되는 내용을 비교합니다.
**점수(Scoring)**는 파트 1과 같습니다: 정확한 체인은 1점을 얻고, 문서화된 근사치는 0.5점, 건너뛰기 또는 잘못된 체인은 0점입니다. R은 실제 로케이터에 대한 점수이고, S는 엣지 케이스에 대한 점수이며, 둘 다 100점 만점입니다. 컨버터는 R 96.0 / S 93.6점을 받았는데, 이는 이 채점 기준에서 최대치입니다 (일부 로케이터는 근사치만 존재합니다). 저는 또한 컨버터의 579개의 사용 가능한 체인을 100%로 간주하고 각 모델을 그 숫자에 맞춰 측정했습니다.
**잘못된 체인(wrong chain)**이란 WDA가 거부하거나 다른 요소를 찾는 경우를 말합니다. 이는 건너뛰기보다 더 나쁩니다. 왜냐하면 유효한 로케이터처럼 보이기 때문입니다: 다른 요소를 찾는 체인은 잘못된 버튼을 누르고, Appium 드라이버는
출력 형식은 id별로 하나의 JSON 항목이어야 하며, -ios class chain: 접두사가 붙은 체인이거나 이유와 함께 skip이어야 합니다.
모델 및 노력 수준(effort level)별로 한 번씩 실행했습니다. 비용은 CLI가 보고하는 API 등가 금액입니다. 저는 실제로 Claude Pro 플랜(월 20유로)에서 모든 것을 실행했기 때문에 사용량 제한이 적용됩니다. 이것이 xhigh를 건너뛰게 했고 Opus의 max는 완료할 수 없었습니다. 시간은 벽시계 시간(wall time)이며, 세 번의 실행이 하나의 계정에서 병렬로 공유되었습니다. 스크립트와 원본 출력: audit/llm/.
일반적인 요청 (A plain request)
각 Claude 5.5 모델의 최선의 노력 수준(best effort level)을 이용한 일반적인 요청:
| Model | R | S | vs conv. | Wrong | Min | Cost |
|---|---|---|---|---|---|---|
| Converter | 96.0 | 93.6 | 100 % | 0 | seconds | free |
| ... | ||||||
| "vs conv."는 컨버터의 579개에 대한 사용 가능한 체인(usable chains)을 의미하고, "Wrong"은 잘못된 체인을, "Min"은 분 단위 실행 시간을 의미합니다. |
- 실제 로케이터에서는 모델들이 근접합니다. R 94–95 대 96.0: 대부분의 실제 로케이터는 간단하며 (
name,label, type,contains), 모든 모델이 이를 변환합니다. - 격차는 예외적인 경우에 있습니다. S 64–82 대 93.6: 위치(positions), 문자열 함수(string functions), 중첩된 술어(nested predicates), 이스케이프 처리(escaping) 등입니다.
- 모든 실행에서 잘못된 체인이 발생했습니다. 564개 중 네 개는 적게 들릴 수 있지만, 그중 하나가 결제 버튼의 로케이터일 수도 있습니다.
노력 수준을 높이면 도움이 될까요? (Does a higher effort help?)
Claude Code에는 low부터 max까지의 노력 수준이 있으며, 더 높은 수준은 모델이 더 오래 생각하도록 합니다. 저는 각 5.5 모델을 low, medium, high, 그리고 max에서 실행했습니다 (Opus의 max는 사용량 제한 내에서 완료되지 않았습니다).
[
- Opus:
low와medium은 동일한 답변을 내놓았으며,high는 비용이 39% 더 들었지만 S 점수에서 1점을 추가했습니다. - Sonnet: 유일하게 의미 있는 단계는
low→medium입니다 (S 68.5 → 77.6, 비용 동일).max는 비용과 시간이 각각 4.6배 증가하는 대신 3.6점만 더 올렸습니다. - Haiku:
medium에서 가장 뛰어납니다.low에서는 0부터 시작하는 인덱스([0])를 사용하며 39개의 잘못된 체인을 만들었고,max에서는 목록의 4분의 1을 건너뛰었습니다.
max 설정에서는 출력 토큰 중 79–89%가 답변 개선에 기여하지 않은 생각들이었습니다. medium만으로 충분하며, Opus의 경우 low로도 충분합니다.
모든 노력 수준
| 모델 및 노력 | R | S | 잘못된 체인 수 | 시간(분) | 비용 |
|---|---|---|---|---|---|
Haiku low | 91.3 | 51.3 | 39 | 8.6 | $0.39 |
| ... |
xhigh는 실행되지 않았습니다. Opus의 max 설정은 사용 가능한 결과 없이 Pro 플랜의 5시간 사용 제한에 두 번 도달했습니다 (총 81분 및 약 $13).
이전 모델들
이전 세대 모델들에게 동일한 단순 요청을 각각 한 번씩 실행해 본 결과:
| 모델 | R | S | vs conv. | 잘못된 체인 수 | 분 | 비용 |
|---|---|---|---|---|---|---|
| Converter | 96.0 | 93.6 | 100 % | 0 | — | 무료 |
| ... |
¹ 100개의 로케이터를 7번 실행한 결과: 전체 목록을 작성하는 데 20분이 걸렸습니다.
² 세 번의 모든 실행에서 변환하는 대신 Python 컨버터를 작성했습니다. 이는 스크립트를 실행하고 모든 답변을 반환한 유일한 실행이었습니다.
각 새로운 세대는 엣지 케이스(edge cases)에서 더 높은 점수를 받았고, 잘못된 체인 수가 적었으며, 더 빠르고 저렴했습니다. Opus 4.6은 Haiku가 $0.28에 6분 만에 수행한 것보다 못한 결과를 내는 데 47분이 걸렸습니다.

모델들이 잘못 처리하는 부분
잘못된 체인들은 무작위가 아닙니다. 동일한 다섯 가지 실수가 반복적으로 나타납니다:
| 실수(Mistake) | 잘못된 이유(Why it is wrong) | 발생 위치(Where) |
|---|---|---|
| 원시 줄 바꿈으로 작성된 리터럴 내부의 줄 바꿈 | WDA가 체인을 구문 분석할 수 없음 | 11회 실행 중 10회, 모든 Sonnet 및 Opus |
| ... |
모델들은 또한 변환할 수 있는 것들을 건너뛰기도 합니다. 일반적인 요청만으로는 Opus가 모든 레벨에서 matches(), ends-with(), 그리고 lower-case()를 "XPath 2.0 함수"로 거부했습니다. WDA는 이를 XPath 확장(extension)으로 등록하므로, 드라이버 상에서 유효한 로케이터입니다.
반대 방향도 존재합니다. 초기 실행에서 일부 모델은 당시 컨버터가 건너뛰거나 근사치만 처리했던 30개 로케이터에 대한 정확한 체인을 찾아냈습니다(예: OR 술어 하나로 통합된 유니온, not(), 리터럴 내부의 따옴표와 백틱, 문자열 함수). 저는 에뮬레이터에서 확인하고, XCTest가 술어를 평가하는 방식에 따라 시뮬레이터와 iPhone에서도 확인한 후 이러한 형태들을 컨버터에 추가했습니다. 따라서 LLM 실행 덕분에 컨버터가 개선되었고, 그 이후로는 어떤 모델도 어떤 로케이터에 대해 이를 앞지르지 못했습니다.
규칙이 포함된 프롬프트(A prompt with rules)
위의 실수들 대부분은 WDA를 아는지 여부에 관한 것이지 지능에 관한 것이 아닙니다. 그래서 저는 이것들을 일반적인 규칙(구조, 이스케이핑, 속성, 위치, 건너뛸 항목 등)으로 정리하여 동일한 5.5 버전 세 번의 실행을 다시 진행했습니다. 해당 규칙은 audit/llm/prompt-v4.md에 담겨 있으며, 약 90줄 분량입니다. 여기에는 특정 로케이터에 대한 답변은 없습니다.
| 모델(Model) | R | S | vs conv. | 오답(Wrong) | 최소 비용(Min) | 비용(Cost) |
|---|---|---|---|---|---|---|
| 컨버터(Converter) | 96.0 | 93.6 | 100 % | 0 | — | 무료(free) |
| ... |
상단 값은 일반적인 요청을 의미하고, 하단 값은 규칙이 적용된 동일한 모델을 의미하며, 변화량은 괄호 안에 표시되어 있습니다. 열 이름은 첫 번째 표와 같습니다.
- R은 거의 움직이지 않았습니다. 실제 로케이터의 경우 모델들은 이미 최고 수준이었습니다.
- S는 5(Opus), 16(Sonnet), 8(Haiku)만큼 상승하여, 세 모델 간의 격차가 줄어들었습니다.
- 왜 Opus는 컨버터 대비 96.7%에 머무르는가. 규칙은 12개의 로케이터를 수정했습니다: 기존 잘못된 체인 4개 중 3개와 WDA가 지원하는 항목(
matches(),ends-with(),lower-case(),@x,@index,XCUIElementTypeAny)을 건너뛴 9가지 경우입니다. 하지만 모델은 더 신중해져서 다른 12개도 건너뛰었습니다: 정확한 체인이 없는 것이 7개라 건너뛰는 것이 맞고, 컨버터가 변환할 수 있는 것이 5개입니다(self::, 두 타입의 합집합, 부분 타입 이름, 인덱스가 포함된 절대 경로, 괄호 안의 인덱스). 12개가 들어가고 12개가 나갔습니다. 네 번째 잘못된 체인이 올바른 건너뛰기로 바뀌었습니다. - Opus와 Sonnet은 잘못된 체인을 만들지 않았습니다. Haiku는 여전히 두 가지 종류의 실수(그중 하나가 네 번)를 했기 때문에 확인이 필요합니다.
- 여전히 어떤 모델도 컨버터보다 앞서지 못했습니다. 모델당 한 번 실행했을 때, S에서의 차이는 약 3포인트로 노이즈 수준입니다.
규칙 프롬프트 구축 과정
세 가지 버전이 걸쳐 진행되었으며, 각 버전은 하나의 규칙을 변경했습니다. 첫 번째 버전에서는 잘못된 체인은 없었지만, @type에 대한 지나치게 신중한 규칙 때문에 변환 가능한 76개의 실제 로케이터를 건너뛰었습니다. 이 규칙을 좁히자 문제가 해결되었습니다. 세 번째 버전에서는 `contains(@enabled,
- 컨버터가 먼저다. 무료이고, 오프라인이며, 몇 초 만에 작동하고, 매번 같은 답변을 주며, 틀린 체인을 만들지 않는다. 모델이 한 것 중 더 나은 것은 아무것도 없었다.
- 컨버터가 건너뛴 것에 대해서만 그리고 최신 세대인 Opus 5.5 또는 Sonnet 5.5를
low또는medium설정으로, 프롬프트에 규칙을 포함하여 사용한다. Haiku 5.5가 여섯 배 저렴하지만, 규칙이 있음에도 불구하고 틀린 체인을 만들었다. 대부분의 건너뛴 항목은 정확한 체인이 아예 없으므로, 모델에게 변환하기보다는 그 이유를 설명하도록 기대하는 것이 좋다. - 모델이 작성하는 모든 체인을 화면에서(또는 harness로) 확인한 후에 XPath를 대체해야 한다.
max에 돈을 쓰지 마라. 비용이 몇 배 더 들고, 최대 여섯 배 더 오래 걸리며, 기껏해야 S 점수의 몇 가지 포인트를 제공할 뿐이다.
Claude Code를 사용한다면, 해당 저장소에는 정확히 이 작업을 수행하는 스킬이 있다: 컨버터를 실행한 다음, 건너뛴 각 로케이터를 설명하고 규칙에 따라 체인을 제안하며, 이는 미검증(unverified)으로 표시된다.
한계점
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기