Community코딩 & 개발github.com

Mcube333/appium-java-test-writer

Appium Java 모바일 자동화 테스트(iOS/Android)를 수동 테스트 케이스로부터 작성하거나, 기존 Python/Appium(pytest) 테스트를 Java로 마이그레이션합니다. ThreadLocal 드라이버를 사용한 병렬 실행, 명시적 조건 기반 대기, 크로스 플랫폼 Page Object Model, W3C 제스처, TestNG 및 Allure를 활용합니다.

appium-java-test-writer란 무엇인가요?

이 스킬은 모바일 앱 자동화 테스트를 Java로 작성하는 전문 도우미입니다. 사용자가 수동 테스트 케이스를 제공하면 이를 분석하여 Android와 iOS 모두에서 동작하는 완전한 Appium Java 테스트 스크립트를 생성합니다. 또한 기존 Python/Appium(pytest) 코드를 Java로 변환할 때 단순한 번역을 넘어, `time.sleep`을 명시적 대기로, `TouchAction`을 W3C 제스처로, 전역 드라이버를 ThreadLocal로 교체하는 등 반패턴을 함께 수정합니다. 결과물은 TestNG 기반이며 Allure 보고서를 통해 케이스 ID와의 추적성을 제공하고, `@AndroidFindBy`/`@iOSXCUITFindBy` 어노테이션을 활용한 크로스 플랫폼 로케이터를 지원합니다. Claude Code, Cursor, Codex 등 AI 에이전트 환경에서 사용 가능하며, 사용자가 "Android/iOS 플로우 자동화", "pytest를 Java로 변환", "Appium 테스트 작성"과 같은 요청을 할 때 특히 유용합니다.

지원 대상~Claude Code~Codex CLI~Cursor
Part ofMobile
npx skills add https://github.com/Mcube333/claude-skills-for-qa/tree/HEAD/appium-java-test-writer

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Appium Java 테스트 라이터

SDET가 직접 작성한 것처럼 보이는 모바일 테스트를 생성합니다: Android와 iOS를 하나의 코드베이스로, 여러 기기에서 병렬 안전, sleep 없음, java-client 9+에서 동작하는 제스처, 그리고 수동 케이스 ID로 추적 가능한 Allure 보고서까지 제공합니다. 또한 Python → Java 마이그레이션(실제 업무에서 흔한 작업)을 충실히 처리하며, 단순한 글자 변환에 그치지 않습니다.

모드 결정

  • 수동 케이스 → Java: Workflow A를 따릅니다.
  • Python/Appium 코드 → Java: Workflow B를 따릅니다. 먼저 references/python-to-java-migration.md를 읽으세요.
  • 프레임워크 스캐폴딩: references/framework-scaffold.md의 파일을 사용자의 앱과 플랫폼에 맞게 조정하여 생성합니다.

사용자가 기존 Java 프레임워크 파일(BaseTest, 스크린 클래스, testng.xml, capabilities)을 공유하면, 해당 컨벤션을 참조 파일보다 우선하여 따릅니다.

Workflow A: 수동 케이스 → 테스트

  1. 정규화: 각 케이스를 ID, 제목, 우선순위, 플랫폼, 전제 조건, 테스트 데이터, 단계, 예상 결과로 정리합니다. 플랫폼별 단계(Android 뒤로 가기 버튼, iOS 권한 알림)를 기록합니다.
  2. 스크린 및 컴포넌트: 스크린당 하나의 클래스; 재사용 가능한 위젯(하단 네비, 툴바, 바텀 시트)은 컴포넌트 클래스로 작성하여 스크린에 조합합니다. 스크린 메서드는 사용자 의도를 표현하고 Allure @Step("...")을 포함합니다. 네비게이션 동작은 다음 스크린 객체를 반환합니다.
  3. 로케이터 — 동일 필드에 어노테이션을 사용한 크로스 플랫폼:
    @AndroidFindBy(accessibility = "login-button")
    @iOSXCUITFindBy(accessibility = "login-button")
    private WebElement loginButton;
    
    우선순위: accessibility id → Android resource-id / iOS name → UiAutomator / iOS predicate 또는 class chain → XPath는 마지막(iOS에서 느리고, 모든 곳에서 취약; 사용 시 주석으로 이유 설명). 페이지 소스, Appium Inspector 출력 또는 스크린샷이 제공되지 않은 경우 // TODO-VERIFY 로케이터로 표시합니다. 한 플랫폼의 로케이터만 알려진 경우, 해당 로케이터를 작성하고 다른 어노테이션은 TODO-VERIFY로 남겨두고 맹목적으로 복사하지 않습니다.
  4. 테스트: 케이스당 하나의 @Test, 동작 기반 메서드 이름, @TmsLink에 케이스 ID, @Epic/@Feature/@Story/@Severity (P0 → BLOCKER/CRITICAL, P1 → NORMAL, P2+ → MINOR). 데이터 변형 → @DataProvider (첫 번째 열에 케이스 ID, 본문에 Allure.link(caseId, "tms", caseId)). 모든 예상 결과는 assertion이 됩니다.
  5. 디바이스/앱 상태: 비기본 capabilities(권한 대화상자 → autoGrantPermissions=false, 온보딩 → 클린 설치 / noReset=false, 에뮬레이터 전용 기능(지문 등))가 필요한 케이스를 별도 그룹으로 분류하거나 오버라이드를 기록합니다.
  6. 전제 조건: 긴 터치 시퀀스보다 딥 링크(driver.get("myapp://cart") on Android, mobile: deepLink) 또는 API 설정을 선호합니다. 가능하면 API/세션을 통한 로그인 전제 조건을 사용합니다.
  7. 자동화 불가능한 경우(실제 SMS OTP, 실제 결제, 시뮬레이터 미지원 바이오메트릭, 주관적 시각적 확인): "Not automated" 아래에 대안(테스트 OTP, 샌드박스 결제, 시뮬레이터/에뮬레이터에서 mobile: enrollBiometric/sendBiometricMatch, 시각 비교 도구)과 함께 나열합니다.

Workflow B: Python → Java 마이그레이션

  1. references/python-to-java-migration.md를 읽습니다.
  2. 먼저 구조를 매핑(conftest fixture → BaseTest/팩토리, 페이지 모듈 → 스크린 클래스, parametrize → @DataProvider)한 후 코드를 번역합니다.
  3. 반패턴을 포팅하지 말고 수정합니다: time.sleep → 명시적 대기, TouchAction/MultiAction → W3C Actions 또는 mobile: 제스처, desired-capabilities 딕셔너리 → UiAutomator2Options/XCUITestOptions, 전역 드라이버 → ThreadLocal.
  4. 테스트 의도와 assertion은 동일하게 유지합니다. Python 테스트가 약하게 assertion한 경우(예: assert element) 또는 실패를 숨긴 경우(try/except: pass, 조건문 내 assertion) 수정하고 마이그레이션 테이블에서 언급합니다. 원래 테스트가 실패할 수 없었을 수 있기 때문입니다.
  5. 마이그레이션 테이블을 출력합니다: Python 파일/함수 | Java 클래스/메서드 | 번역 외 변경 사항

대기: 명시적 및 조건 기반

  • 암시적 대기는 0입니다. 암시적 대기와 명시적 대기를 혼합하면 예측 불가능한 타임아웃이 발생합니다.
  • 절대 Thread.sleep을 사용하지 마세요. WebDriverWait와 ExpectedConditions(visibilityOf, elementToBeClickable, invisibilityOf, textToBePresentInElement, attributeToBe)를 BaseScreen의 헬퍼를 통해 사용하세요.
  • 시간이 지나기를 기다리는 대신 로더/스피너가 사라질 때까지 기다리세요.
  • 타임아웃은 인라인 숫자가 아닌 설정에서 가져옵니다.
  • 리스트나 캐러셀을 다시 렌더링하는 동작 후에는 항상 이후에 참인 신호(시트 닫힘, 로더 사라짐, 리스트 존재, 개수가 예상과 일치)를 기다리세요. "첫 번째 항목 텍스트 변경됨"을 기다리지 마세요. 예상 값이 이미 있을 수 있어 대기가 타임아웃됩니다. BaseScreen의 wait는 StaleElementReferenceException을 무시하므로 조건 내에서 다시 쿼리합니다.

제스처

java-client 9는 TouchAction/MultiAction을 제거했습니다. 다음을 사용하세요:

  • 스크롤하여 요소 찾기: Android AppiumBy.androidUIAutomator("new UiScrollable(...).scrollIntoView(...)"); iOS mobile: scroll와 predicateString.
  • 스와이프/드래그/길게 누르기: 플랫폼 mobile: 제스처(Android mobile: swipeGesture, longClickGesture; iOS mobile: swipe, touchAndHold) 또는 크로스 플랫폼 사용을 위해 BaseScreen의 W3C PointerInput 시퀀스. references/framework-scaffold.md → 제스처를 참조하세요.

병렬 안전

드라이버는 테스트당(또는 사용자가 속도를 요청한 경우 클래스당) 생성된 ThreadLocal<AppiumDriver>에 있으며, quit() 후 항상 remove()됩니다. 각 병렬 디바이스는 고유한 udid와 testng.xml 매개변수에서 제공되는 고유한 systemPort(Android) / wdaLocalPort(iOS)가 필요합니다. 정적 드라이버나 정적 요소 상태는 금지입니다.

출력 형식

  1. 파일: import를 포함한 완전한 컴파일 가능한 파일, 각각 경로 제목 아래에 위치합니다. 약 3개 이상의 파일이거나 사용자가 다운로드를 원할 경우, 프로젝트 폴더로 디스크에 작성합니다.
  2. 추적 테이블(Workflow A) 또는 마이그레이션 테이블(Workflow B).
  3. 자동화되지 않음 / 격차.
  4. 확인 필요: TODO-VERIFY 로케이터, 가정된 capabilities(앱 경로, 패키지/액티비티, 번들 ID), 플랫폼 전용 단계의 개수와 목록.

설명은 간결하게 유지하고, 코드가 전달물입니다.

기밀성

포트폴리오/공개 작업의 경우, 패키지 com.example(또는 사용자의 패키지), 공개 데모 앱을 사용하고 회사 이름, 내부 앱 ID, 내부 URL, 실제 전화번호/이메일, 독점 이벤트 이름을 중립적인 것으로 교체합니다. 한 줄에 교체 사실을 언급합니다.

참조 파일

  • references/framework-scaffold.md: pom.xml, 설정, ThreadLocal + Options 클래스가 있는 DriverFactory, 실패 시 Allure 스크린샷/페이지 소스가 포함된 BaseTest, 대기 헬퍼 및 제스처가 포함된 BaseScreen, 병렬 디바이스를 위한 testng.xml.
  • references/python-to-java-migration.md: Python Appium/pytest 관용구와 Java/TestNG의 나란히 매핑, 작업된 마이그레이션 예제.
  • references/example-swaglabs.md: 공개 Sauce Labs 샘플 앱의 수동 케이스 → 스크린 → 테스트.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

관련 스킬