View in English

  • 메뉴 열기 메뉴 닫기
  • Apple Developer
검색
검색 닫기
  • Apple Developer
  • 뉴스
  • 둘러보기
  • 디자인
  • 개발
  • 배포
  • 지원
  • 계정
페이지에서만 검색

빠른 링크

5 빠른 링크

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 주제
  • 전체 비디오
  • 소개

더 많은 비디오

  • 소개
  • 요약
  • 자막 전문
  • 코드
  • 기록, 재생 및 검토: Xcode로 UI 자동화

    Xcode에서 XCUIAutomation 테스트를 기록, 실행 및 유지 관리하는 방법을 학습하세요. 테스트 계획 구성을 사용하여 수십 개의 로컬, 기기 유형 및 시스템 조건에서 XCTest UI 테스트를 다시 재생하세요. Xcode 테스트 보고서를 사용하여 테스트 결과를 검토하고 실행 스크린샷 및 비디오를 다운로드하세요. 또한 손쉬운 사용을 통해 앱이 자동화에 대비하도록 준비시키고 고품질의 안정적인 자동화 코드를 작성하는 모범 사례를 소개합니다.

    챕터

    • 0:00 - 서론 및 어젠다
    • 3:58 - UI 자동화 개요
    • 6:26 - 앱 자동화 준비하기
    • 11:32 - 상호작용 기록하기
    • 17:30 - 여러 구성에서 다시 재생하기
    • 20:54 - 비디오 및 결과 검토하기
    • 24:16 - 다음 단계

    리소스

    • Delivering an exceptional accessibility experience
    • Improving code assessment by organizing tests into test plans
    • Performing accessibility testing for your app
      • HD 비디오
      • SD 비디오

    관련 비디오

    WWDC24

    • Swift Testing 소개

    WWDC23

    • 앱에서 접근성 감사 수행하기
    • SwiftUI와 UIKit으로 접근성 높은 앱 구축하기
    • Xcode 테스트 보고서로 빠르게 오류 해결하기
    • Xcode Cloud에서의 실용적인 작업 흐름 만들기

    WWDC22

    • Xcode Cloud를 위한 빠르고 안정적인 테스트 작성

    WWDC21

    • SwiftUI Accessibility: Beyond the basics
  • 비디오 검색…

    안녕하세요, 저는 Xcode 팀의 엔지니어인 Max입니다 Xcode에는 멋진 기능과 경험이 정말 많습니다 압도되는 느낌이 들 수도 있죠 예를 들어 클릭 한 번이면 수많은 기기, 언어 및 구성으로 앱을 실행할 수 있다는 것을 알고 계셨나요? 게다가 각 실행을 고품질 비디오로 기록할 수 있습니다 Xcode의 UI 자동화 기능을 활용하면 가능합니다 이 기능이 어떻게 작동하는지 보죠 먼저 UI 자동화의 개요를 둘러봅니다 그런 다음 앱을 준비하고 자동화 코드로 상호작용을 기록하며 여러 기기와 언어에서 자동화를 재생합니다 마지막으로 결과의 비디오 기록을 시청하고 각 실행의 통과/실패 여부에 대한 보고서를 확인합니다

    우선 UI 자동화가 작동하는 방식의 개요를 살펴보겠습니다

    Xcode에는 Swift Testing, XCTest 라는 테스트 프레임워크 둘이 있죠 두 프레임워크 모두 여러 구성에서 앱과 소스 코드를 빠르게 테스트할 수 있습니다

    XCTest를 가져올 때 XCUIAutomation 프레임워크가 자동으로 포함됩니다 XCUIAutomation을 사용하면 앱을 자동화하고 사람처럼 앱과 상호작용이 가능하죠 이들 프레임워크는 함께 완전한 앱 테스트 모음으로 기능하는데 제 생각에는 상당히 유용합니다 완전한 앱 테스트 모음은 일반적으로 유닛 테스트와 UI 자동화 테스트로 구성됩니다 유닛 테스트는 앱의 논리와 모델을 테스트하며 Swift Testing은 사용자 인터페이스가 없는 프레임워크와 Swift 패키지에서도 테스트를 실행할 수 있습니다 반면 UI 자동화 테스트는 앱의 사용자 경험과 앱과 Apple 하드웨어 간 통합 일반적인 작업 흐름의 동작을 검증합니다

    흔히 테스트 모음에는 UI 테스트보다 유닛 테스트가 많으며 코드 전체를 다루는 것을 목표로 삼아야 합니다 하지만 UI 자동화 테스트에서는 앱의 모습, 행동, 운영 체제의 나머지 부분과 통합되는 방식을 확인할 수 있습니다 이렇게 하면 이점이 매우 많습니다

    예를 들어 사람이 탭, 스와이프 클릭 등의 제스처를 사용해 보듯 앱을 테스트할 수 있습니다 VoiceOver, 음성 명령 Dynamic Type과 같은 보조 기술을 사용하는 사람이 앱을 어떻게 인식하는지 이해할 수 있습니다

    앱이 지원하는 모든 언어 및 지역에서 앱이 실행되는 양상을 확인하고 앱의 모습에 큰 영향을 미치는 언어에 집중할 수 있습니다 문자열이 긴 언어, 오른쪽에서 왼쪽으로 쓰는 언어처럼 말입니다 동작 버튼, 카메라 버튼 Apple TV 리모컨, Apple Watch의 Digital Crown과 같은 Apple 하드웨어 기능과 앱 간의 통합을 테스트할 수 있습니다 마지막으로 앱의 시작 성능을 테스트할 수 있습니다 사용자가 앱 사용 시작에 걸리는 시간을 이해하는 데 중요한 지표죠 UI 자동화 작업 흐름을 설정할 때 세 가지 주요 단계가 있습니다 기록, 재생, 검토입니다

    탭, 스와이프, 하드웨어 버튼 누름 등의 상호작용을 기록하면 Xcode가 이 내용을 자동으로 코드로 작성해 줍니다 그런 다음 여러 기기, 언어 지역 및 기기 방향으로 상호작용을 재생합니다 기기와 Xcode Cloud 모두에서요 마지막으로 이 모든 구성의 앱 실행을 비디오로 기록한 결과를 검토하며 통과한 경우와 실패한 경우를 확인합니다 UI 자동화는 모든 Apple 플랫폼에서 지원됩니다 iOS, iPadOS, macOS, watchOS, tvOS, iPad용 visionOS 모두입니다 동일한 자동화를 여러 플랫폼에서 실행할 수도 있습니다 따라서 자동화를 한 번 빌드한 후 모든 지원 기기에서 실행 가능합니다 클릭 한 번으로 코드 변경 없이 Mac, iPhone 및 Vision Pro에서 앱 실행 방식을 확인할 수 있습니다 UI 자동화가 어떻게 작동하는지 간략히 살펴보겠습니다 UI 자동화는 사람처럼 제스처와 하드웨어 이벤트로 앱과 상호작용합니다 자동화는 앱과 완전히 독립적으로 실행되므로 앱 모델과 데이터에는 직접 접근할 수 없습니다

    UI 자동화는 수행할 제스처를 운영 체제에 알려 주고 제스처가 한 번에 하나씩 완료되기를 동기식으로 대기합니다

    이러한 동작에는 앱 실행 버튼 및 탐색과의 상호작용 다크 모드 등의 시스템 상태 설정 원하는 경우 기기의 시뮬레이션된 위치 설정까지 포함됩니다 접근성은 Apple의 핵심 가치 중 하나입니다 Apple의 보조 기술은 신체, 시각 청각이나 운동 장애와 관계없이 누구나 앱을 사용할 수 있도록 해 줍니다 Apple은 이러한 기술 대부분이 개발자의 개입 없이도 기본적으로 앱에서 동작하도록 하기 위해 최선을 다합니다 이외에도 추가 지원을 하면 앱의 경험이 더욱 풍부해지고 자동화가 더 쉽게 진행됩니다 말하자면 접근성은 UI 자동화를 실현하는 기본 프레임워크에 해당합니다 접근성 경험이 우수하면 UI 자동화 경험 또한 우수합니다 접근성은 요소 유형, 레이블, 값 프레임 등의 정보를 UI 자동화에 직접 제공합니다 하지만 접근성 측면에서 보는 것은 실제 사람이 보는 것과 반드시 일대일로 대응되지는 않습니다 예를 들어 보겠습니다 화면에 그레이트 배리어 리프 버튼이 UI에 표시되어 있는데 접근성 측면에서 내용은 그보다 더 많습니다 물론 접근성으로 요소 유형 및 레이블을 보고 UI 자동화에 노출할 수 있습니다 하지만 식별자 속성 또한 노출됩니다 접근성 식별자로 화면의 요소를 주변의 모든 요소에 상대적으로 고유하게 설명할 수 있습니다 이 식별자는 현지화되도록 디자인되지 않았으므로 모든 언어 또는 기기에서 동일 UI 요소 참조에 사용 가능합니다

    체크상자와 기타 스테이트풀 요소의 경우 값 속성을 사용할 수 있습니다 이 속성은 요소의 현재 상태를 접근성과 UI 자동화에 나타냅니다

    접근성에 대해 자세히 알아보려면 WWDC23의 “SwiftUI 및 UIKit으로 접근성 높은 앱 구축하기” 또는 WWDC21의 “SwiftUI 접근성: 기본 사항 그 이상”을 확인하세요

    UI 자동화가 접근성과 함께 어떻게 작동하는지 살펴보았습니다 이제 앱 자동화를 준비해 보죠

    먼저 접근성 식별자를 추가합니다 그런 다음 앱의 접근성을 간단히 검토합니다 마지막으로 새로운 UI 테스트 대상을 추가하여 상호작용을 코드로 기록할 준비를 합니다 시작하기 전에 주의점이 있습니다 앱은 이미 UI 자동화 및 UI 기록이 즉시 가능한 상태이며 개발자의 개입이 필요하지 않다는 것입니다 지금 다루려는 단계는 필수는 아니지만 더 우수하고 품질이 높은 결과를 기대할 수 있습니다 접근성 식별자는 SwiftUI, UIKit 또는 AppKit로 작성한 보기 코드에서 추가할 수 있습니다 접근성 식별자는 자동화를 위해 앱의 요소를 고유하게 식별하는 데 가장 좋은 방법입니다 현지화된 문자열 또는 동적 콘텐츠로 요소에 접근성 식별자를 추가하면 좋습니다 여기에는 데이터 모델에서 발견한 콘텐츠 또는 인터넷에서 다운로드한 콘텐츠가 포함됩니다

    좋은 식별자는 앱 전체에서 고유하고 식별자가 있는 요소의 세부 정보를 충분히 설명하며 정적이고 콘텐츠의 변화에 반응하지 않는 식별자입니다

    제목과 설명은 변경될 수 있지만 좋은 식별자는 반드시 식별자와 연결된 요소의 콘텐츠를 설명합니다 그래야만 멋진 랜드마크가 변함없이 유지될 수 있습니다

    SwiftUI에서는 UI 요소에 accessibilityIdentifier 수정자를 추가할 수 있습니다 보기 및 상위 보기를 접근성으로부터 숨기지 않는 한 이 수정자는 인식됩니다

    보기의 인스턴스별로 식별자를 만드는 것이 좋습니다 특히 앱에서 여러 번 사용되는 보기의 경우 더욱 그러합니다 이 예에서는 랜드마크의 id 속성을 사용하여 각각에 대해 고유한 식별자를 만듭니다

    UIKit에서 accessibilityIdentifier 속성은 보기가 접근성 요소인 한 모든 UIView에 설정할 수 있습니다 컨트롤, 텍스트 및 이미지와 같은 대부분의 UI 보기는 기본적으로 접근성 요소이므로 이때 작업이 필요하지 않습니다

    accessibilityLabel accessibilityTraits 및 accessibilityValue 등의 속성은 VoiceOver 같은 보조 기술은 물론 UI 자동화에도 유용합니다

    하지만 accessibilityIdentifier 속성은 VoiceOver에서 소리내어 읽지 않고 앱 사용자에게 노출되지 않습니다 따라서 자동화에만 유용한 정보를 제공하는 데 좋은 방법입니다 표 셀의 인덱스나 이미지의 기호 이름 등 말입니다 Xcode의 코딩 보조가 접근성 식별자를 대신 추가하도록 할 수도 있습니다 예를 들어 “이 보기의 관련 부분에 접근성 식별자 추가”라고 쓰면 그대로 수행됩니다 코딩 보조는 랜드마크에 대한 id 속성을 사용하여 각 식별자를 완전히 고유하게 만드는 방법도 압니다 멋지죠 UI 기록을 시작하기 전에 앱의 전반적인 접근성 동작을 검토하는 것이 좋습니다 치과에 가기 전에 치실질을 하는 것과 같습니다 그동안 얼마나 잘 해 왔는지 곧 알게 되죠 유용한 미리보기를 확인하는 방법이라 할 수 있습니다 Xcode는 손쉬운 사용 인스펙터 앱과 함께 제공됩니다 이 앱으로 접근성 문제를 찾고 진단하고, 해결할 수 있습니다 인스펙터는 Xcode 최상위 메뉴의 Open Developer Tool 아래에서 실행할 수 있습니다 Spotlight에서도 실행 가능합니다

    손쉬운 사용 인스펙터는 플랫폼에 관계없이 앱의 모든 보기의 접근성 값을 나열할 수 있습니다 검사하려는 플랫폼을 선택한 다음 Element inspector를 클릭하고 해당 플랫폼에서 확인하려는 UI 요소와 상호작용하면 됩니다 요소 속성 목록이 표시되는데요 그중 일부는 Basic 섹션에 있는 것과 마찬가지로 UI 자동화에 매우 유용합니다 정보가 부족한 보기의 경우 앱의 소스 코드를 변경하고 내용을 추가해야 할 수 있습니다 속성 이름을 클릭하면 각 속성에 대해 자세히 확인할 수 있습니다 팝오버는 정확히 어떤 속성을 설정해야 하는지 알려 주고 이에 대한 문서 등을 제공합니다

    샘플 코드 프로젝트인 “탁월한 접근성 경험 제공”으로 접근성 기능에 대해 자세히 알아볼 수 있습니다 이 프로젝트는 여러 접근성 기능을 사용하는 앱을 위한 유용한 코드 예시를 포함하고 있으며 UI 자동화에 매우 친화적입니다 “앱에서 접근성 테스트 수행하기” 문서에서는 다양한 보조 기술을 사용하여 앱의 접근성을 확인하는 방법에 대해 자세히 알아볼 수 있습니다 자동화를 시작할 준비가 되었다면 자동화 코드를 배치할 새로운 UI 테스트 대상을 추가해야 합니다

    Xcode의 프로젝트 설정 보기에서 대상 목록 아래의 “더하기” 버튼으로 새 대상을 추가합니다

    그런 다음 팝오버에서 UI Testing Bundle을 선택합니다

    Finish를 클릭하면 새로운 UI 테스트 폴더와 템플릿이 프로젝트에 추가됩니다 이 템플릿에는 시작 시 유용한 간단한 테스트가 포함됩니다 이제 모든 상호작용을 Swift 코드로 기록할 준비가 되었습니다 여기서는 iOS 시뮬레이터 및 Xcode를 사용하겠습니다 몇 년 전 어머니와 여자 형제가 저 없이 한 달간 오스트레일리아 여행을 갔었죠 함께 가지 못해서 참 아쉬웠는데요 다행히 이를 위한 앱이 있습니다 올해 WWDC에서 나온 랜드마크 샘플 프로젝트를 사용해 저만의 휴가를 계획하는 거죠 앱의 추후 버전에서 작업 흐름이 깨지지 않도록 여행을 계획하는 상호작용을 기록해 보겠습니다 UI 테스트 소스 파일을 처음 열면 팝오버가 나타나 UI 기록을 시작하는 방법을 알려 줍니다 이제 사이드바의 버튼을 사용해 UI 기록을 시작하겠습니다 Xcode가 자동으로 빌드하고 시뮬레이터에서 앱을 재실행합니다

    앱이 실행되었으니 컬렉션 보기로 이동하겠습니다

    앱과 상호작용하는 과정에서 해당 상호작용을 나타내는 코드가 소스 편집기에 기록됩니다 더하기 버튼을 탭하여 새로운 컬렉션을 추가함으로써 저만의 오스트레일리아 여행 계획을 시작합니다 이제 Edit 버튼을 탭하여 여행 이름을 바꿉니다 여행 이름을 “Max’s Australian Adventure”로 바꿀 수 있습니다

    타이핑 중에 Xcode가 테스트를 최신 상태로 유지해 줍니다

    랜드마크 컬렉션을 편집해 보죠

    그레이트 배리어 리프, 울룰루 등 오스트레일리아 랜드마크를 추가하고 체크 표시를 탭합니다

    컬렉션 보기로 돌아가면 오스트레일리아 랜드마크가 포함된 컬렉션이 추가된 것을 볼 수 있습니다

    Xcode의 Stop Run 버튼은 UI 기록을 중지합니다 기록을 끝낸 후에는 자동화가 원하는 형태인지 확인하기 위해 할 수 있는 몇 가지 작업이 있습니다 먼저 기록된 코드를 검토합니다 이후 XCTest API로 검증을 추가해 앱이 예상대로 작동하는지 확인합니다 마지막으로 더 강력한 테스트를 준비할 수 있는 다른 자동화 API를 살펴봅니다

    기록된 UI 쿼리를 검토하면서 조정할 부분이 있는지 확인해 보겠습니다 기록된 코드의 모든 줄에는 각 UI 요소를 처리할 옵션이 있죠 어떤 옵션을 선택할지는 목표에 따라 다릅니다 각 소스 코드 줄의 드롭다운을 클릭해 선택안을 볼 수 있습니다

    힌트는 적절한 것을 선택해야 오스트레일리아행 비행기에 더 빨리 탑승할 수 있다는 것이죠

    옵션을 선택할 때 몇 가지 권장 사항이 있습니다

    텍스트 요소, 버튼 등 현지화된 문자열이 있는 보기에서 접근성 식별자가 있다면 이것을 선택하는 것이 좋습니다 이러한 식별자가 있으면 이를 UI 기록이 기본적으로 사용합니다

    스크롤 보기의 텍스트와 같이 심도 있게 중첩된 보기의 경우 가급적 가장 짧은 쿼리를 선택하는 것이 좋습니다 이렇게 하면 앱이 변동되더라도 자동화의 탄력성이 유지됩니다

    마지막으로 인터넷에서 다운로드한 동적 콘텐츠나 타임스탬프, 온도처럼 자주 변경되는 콘텐츠는 좀 더 일반적인 쿼리를 사용하거나 접근성 식별자가 있다면 이것을 사용하는 것이 좋습니다

    이 예에서는 식별자나 문자열을 전혀 사용하지 않으며 항상 첫 번째 텍스트 부분을 참조합니다

    이제 선택을 할 차례입니다 편집하여 옵션을 보려는 소스 코드 줄을 클릭하겠습니다 이 모든 쿼리는 상호작용한 요소를 고유하게 식별하므로 잘못된 선택이란 없습니다 향후 이 UI 부분에 대한 참조를 어떻게 저장할지 선택하는 것일 뿐입니다 textFields.firstMatch 옵션을 선택하여 테스트에서 텍스트 필드가 명칭에 관계없이 항상 탭되도록 하겠습니다 드롭다운을 두 번 클릭하면 결과가 소스 코드에 저장됩니다 이제 자동화를 빠르게 다시 실행해 동작이 올바르게 기록되었는지 확인하겠습니다 테스트 다이아몬드를 클릭합니다 앱을 테스트하는 작업은 인내심을 시험하지는 않습니다 자동화 재생 실행은 매우 빠릅니다

    컬렉션이 올바른 이름으로 빠르게 생성되고 위치가 추가되며

    자동화가 통과됩니다 굉장하죠 19시간짜리 항공편보다 훨씬 빨랐네요 이제 예상되는 동작을 확인하고자 코드에 검증을 추가할 수 있습니다 이 예시에서는 그레이트 배리어 랜드마크가 컬렉션에 추가되었음을 검증합니다

    waitForExistence 등의 메서드를 호출해 요소가 나타날 때까지 대기 후 자동화가 넘어가게 할 수 있습니다 더 일반적인 메서드인 wait(for:toEqual:)을 호출하여 XCUIElement의 속성이 예상되는 결과와 일치하는지 검증할 수 있습니다

    두 메서드 모두 XCTest에서 XCTAssert 문과 페어링하여 메서드가 false를 반환하면 테스트가 실패하게 할 수 있습니다

    이제 코드로 가서 컬렉션의 이름에 waitForExistence를 추가해 향후 실행에서도 유지되도록 하겠습니다

    이때 더 강력한 코드를 위해 다른 자동화 API를 살펴보면 좋습니다

    XCTestCase의 setup instance 메서드로 기기가 향후 실행에서 동일한 상태를 유지하게 하면 유용할 수 있습니다 방향, 모양 등의 API를 호출 하거나 위치를 시뮬레이션하여 실행이 시작되기 전에 기기를 올바른 상태로 바꿀 수 있습니다

    앱을 실행하기 전에 launchArguments 및 launchEnvironment 등의 요소를 사용해 launch 메서드가 호출될 때 앱이 해당 매개변수를 사용하도록 할 수 있습니다

    앱이 맞춤형 URL 체계를 지원한다면 XCUIApplication open 메서드로 일치 URL로 직접 열 수 있습니다

    전역 버전도 있는데 이 버전에서는 기기의 기본 앱을 사용하여 URL을 엽니다

    마지막으로 UI 테스트 내에서 앱의 접근성 감사를 수행할 수 있습니다 “앱에서 접근성 감사 수행하기” WWDC23 세션이 유용합니다 이렇게 상호작용을 기록하고 자동화를 설정했으니 이제 테스트를 데스크 클라우드처럼 여러 구성으로 재생하도록 구성해 보겠습니다 신규 또는 기존 테스트 계획에 테스트를 추가하면 유용합니다 테스트 계획을 사용하면 개별 테스트를 포함 또는 제외하고 테스트가 실행되는 위치와 방법의 시스템 설정을 지정하며 시간 초과, 반복, 병렬화 실행 순서 등의 테스트 속성을 관리할 수 있습니다

    테스트 계획은 또한 체계와 연관되는데 이를 통해 테스트 계획을 특정 빌드 설정과 페어링할 수 있습니다

    “테스트를 테스트 계획으로 구성하여 코드 평가 개선하기” 문서에서 자세한 관련 내용을 알아볼 수 있습니다 개발자 문서에서 확인 가능합니다

    테스트 계획에서는 첫 화면에서 테스트를 추가 또는 제거하거나 Configurations 탭으로 전환해 테스트 실행 방법을 변경합니다 여러 언어로 앱을 실행하기 위해 여러 구성을 설정할 수 있습니다

    일반적으로 각 로케일은 테스트 계획에서 별도 구성입니다

    특정 로케일 구성에 중점을 둔 설정이 있을 수도 있고 모든 설정에서 공유하는 다른 설정이 있을 수도 있습니다

    독일어처럼 문자열이 긴 언어에 대한 구성이나 아랍어, 히브리어처럼 오른쪽에서 왼쪽으로 쓰는 언어에 대한 구성을 포함하면 유용할 수 있습니다

    Configurations 탭에는 UI 자동화 중심 설정도 있습니다

    여기에는 실행 중에 비디오나 스크린샷을 캡처할지 여부와 나중에 어떤 미디어를 보관할 것인지 여부가 포함됩니다

    기본적으로 비디오와 스크린샷은 실패 실행에 대해서만 보관됩니다 문제를 검토할 수 있도록 말입니다 통과된 실행을 포함해 모든 실행에 대해 보관하려면 “On, and keep all”을 선택합니다 이 설정으로 문서화, 튜토리얼 마케팅 등 다른 목적으로 비디오 기록을 보관할 수 있습니다 Configurations 탭에는 유용한 설정이 많습니다 자세히 알아보려면 WWDC22의 “Xcode Cloud를 위한 빠르고 안정 적인 테스트 작성”을 확인하세요

    Xcode Cloud는 Xcode의 서비스로 App Store Connect에서도 이용 가능합니다 앱 빌드, 테스트 실행, App Store 업로드 작업 등에 유용합니다 모두 클라우드에서 진행되며 여러분 또는 팀의 기기를 사용할 필요가 없습니다 Xcode Cloud는 누구나 매우 유용하다고 느끼실 것 같은데요 랜드마크 앱의 경우 방금 만든 테스트 계획을 사용해 방금 작성한 UI 자동화 전부를 실행하는 Xcode Cloud 작업 흐름이 구성되어 있습니다 이 계획은 시뮬레이터와 동일하게 클라우드에서 실행되며 기기 수와 영어, 아랍어 히브리어, 독일어 등의 구성에 구애받지 않고 iPhone 및 iPad에서 실행됩니다

    Xcode나 App Store Connect의 Xcode Cloud 섹션에서 Xcode Cloud 실행 내역을 볼 수 있습니다 이곳에서 빌드 정보, 로그 실패 설명 등의 개요를 확인할 수 있습니다

    Xcode Cloud를 사용하면 팀이 제 실행 내역을 확인하고 결과와 비디오 기록을 다운로드할 수 있습니다 제가 구름 속에 있더라도 가능하죠 제가 시드니행 비행기 안에 있을 때도 말입니다

    Xcode Cloud에 대해 알아볼 만한 내용은 무한합니다 고급 구성은 WWDC23의 “Xcode Cloud에서의 실용적인 작업 흐름 만들기”를 확인하세요 다양한 구성에서 테스트 계획을 사용해 기록된 테스트를 실행했고 이제 테스트 보고서로 결과와 비디오 기록을 검토할 수 있습니다 Xcode 테스트 보고서에는 테스트 결과 보기, 이해, 진단에 유용한 도구가 있습니다 방금 실행한 자동화에서 실행 중 하나가 실패한 것으로 보입니다 아직은 오스트레일리아 여행의 짐을 쌀 때가 아닌 것 같군요 실패한 테스트로 이동하기 위해 Test 버튼을 클릭한 다음 실패한 실행을 두 번 클릭하여 비디오 기록과 상황에 대한 설명을 확인합니다

    실행 드롭다운에서 이 테스트의 모든 실행을 볼 수 있습니다 덕분에 다양한 언어 등 다양한 구성으로 실행된 테스트의 비디오 녹화 간에 빠르게 전환할 수 있습니다 또한 보조 클릭을 사용하고 Save를 선택하여 비디오를 다운로드할 수 있습니다

    Play로 비디오를 재생합니다

    비디오가 재생되는 동안 UI 상호작용을 보여 주는 점이 비디오 위에 겹쳐서 표시됩니다 이러한 동작은 아래 타임라인에도 점으로 표시됩니다

    다소 시간이 흐른 후 실패한 것 같으므로 조금 넘기겠습니다 타임라인에서 실패 다이아몬드로 실패 순간으로 바로 이동합니다

    실패 메시지가 보이지만 문제가 무엇인지 확실치 않습니다 메시지에는 Max’s Australian Adventure라는 버튼을 찾고 있다고 하는데요 실패 지점에 실제로 무엇이 표시되었는지 보겠습니다

    실패 순간에 비디오 기록의 오른쪽 상단에 표시되던 모든 UI 요소가 오버레이되었습니다

    이 중 하나를 클릭하면 자동화 코드에서 이 요소의 문제를 해결할 방법에 대한 코드 권장 사항을 볼 수 있습니다 Show All을 눌러 대체 예시를 보고 알맞은 것을 찾을 수도 있습니다 문제가 무엇인지 알겠습니다 버튼이 있어야 하는데 버튼이 없군요 그냥 텍스트입니다 얼른 수정하겠습니다

    원하는 샘플을 선택하고 보조 클릭하여 복사합니다

    그런 다음 View Source를 클릭해 테스트로 이동하고 새 코드 줄을 기존 코드 줄 위에 붙여넣습니다

    이제 임시 XCUIApplication 변수를 UI 기록의 앱 변수로 대체할 수 있으며 문제가 해결됩니다

    이제 예상대로 실행될 겁니다 테스트 다이아몬드를 클릭해서 테스트 재실행을 보겠습니다 이번에는 오른쪽에서 왼쪽으로 쓰는 레이아웃에서 앱을 실행해도 동일한 자동화가 작동하는지 아랍어로 테스트를 실행하겠습니다

    자동화에서 빠르게 컬렉션을 만들고 영어에서처럼 이름을 바꿉니다 멋지죠

    자동화가 통과된 것 같습니다 이제 이 세션을 마무리하고 꿈의 여행을 떠날 시간입니다 어머니와 여자 형제가 동행해서 안내해 줄지도 모르겠네요 Xcode 테스트 보고서로 가능한 작업은 훨씬 더 많습니다 다행히 WWDC23 “Xcode 테스트 보고서로 빠르게 오류 해결하기” 세션에서 심도 있게 모두 다룹니다 UI 자동화, 접근성, 현지화 Xcode Cloud, 테스트 보고서가 한데 모여 앱의 품질을 향상하고 전 세계 모두가 앱을 더 쉽게 사용할 수 있도록 한다는 것은 무척 놀랍고 멋진 일입니다 이러한 기술을 단일 흐름으로 통합하는 작업은 정말 즐거웠으며, 개발자들이 어떻게 사용할지 기대가 큽니다

    WWDC24의 “Swift Testing 소개” 세션에서 유닛 테스트 및 Swift Testing에 대해 자세히 알아볼 수 있습니다 추가 질문이나 피드백은 개발자 포럼에서 문의하실 수 있습니다 함께해 주셔서 감사하며 오스트레일리아에서 뵙겠습니다

    • 7:52 - Adding accessibility identifiers in SwiftUI

      // Adding accessibility identifiers in SwiftUI
      import SwiftUI
      
      struct LandmarkDetailView: View {
        let landmark: Landmark
        var body: some View {
          VStack {
            Image(landmark.backgroundImageName)
              .accessibilityIdentifier("LandmarkImage-\(landmark.id)")
            
            Text(landmark.description)
              .accessibilityIdentifier("LandmarkDescription-\(landmark.id)")
          }
        }
      }
    • 8:19 - Adding accessibility identifiers in UIKit

      // Adding accessibility identifiers in UIKit
      import UIKit
      
      struct LandmarksListViewController: UIViewController {
        let landmarks: [Landmark] = [landmarkGreatBarrier, landmarkCairo]
      
        override func viewDidLoad() {
          super.viewDidLoad()
      
          for landmark in landmarks {
            let button = UIButton(type: .custom)
            setupButtonView()
                      
            button.accessibilityIdentifier = "LandmarkButton-\(landmark.id)"
            
            view.addSubview(button)
          }
        }
      }
    • 13:54 - Best practice: Prefer accessibility identifiers over localized strings

      // Example SwiftUI view
      struct CollectionDetailDisplayView: View {
        var body: some View {
          ScrollView {
            Text(collection.name)
              .font(.caption)
              .accessibilityIdentifier("Collection-\(collection.id)")
          }
        }
      }
      
      // Example of a worse XCUIElementQuery
      XCUIApplication().staticTexts["Max's Australian Adventure"]
      
      // Example of a better XCUIElementQuery
      XCUIApplication().staticTexts["Collection-1"]
    • 14:09 - Best practice: Keep queries as concise as possible

      // Example SwiftUI view
      struct CollectionDetailDisplayView: View {
        var body: some View {
          ScrollView {
            Text(collection.name)
              .font(.caption)
              .accessibilityIdentifier("Collection-\(collection.id)")
          }
        }
      }
      
      // Example of a worse XCUIElementQuery
      XCUIApplication().scrollViews.staticTexts["Collection-1"]
      
      // Example of a better XCUIElementQuery
      XCUIApplication().staticTexts["Collection-1"]
    • 14:21 - Best practice: Prefer generic queries for dynamic content

      // Example SwiftUI view
      struct CollectionDetailDisplayView: View {
        var body: some View {
          ScrollView {
            Text(collection.name)
              .font(.caption)
              .accessibilityIdentifier("Collection-\(collection.id)")
          }
        }
      }
      
      // Example of a worse XCUIElementQuery
      XCUIApplication().staticTexts["Max's Australian Adventure"]
      
      // Example of a better XCUIElementQuery
      XCUIApplication().staticTexts.firstMatch
    • 15:49 - Add validations to a test case

      // Add validations to the test case
      import XCTest
      
      class LandmarksUITests: XCTestCase {
      
        func testGreatBarrierAddedToFavorites() {
          let app = XCUIApplication()
          app.launch()
          app.cells["Landmark-186"].tap()
          XCTAssertTrue(
            app.staticTexts["Landmark-186"].waitForExistence(timeout: 10.0)),
            "Great Barrier exists"
          )
      
          let favoriteButton = app.buttons["Favorite"]
          favoriteButton.tap()
          XCTAssertTrue(
            favoriteButton.wait(for: \.value, toEqual: true, timeout: 10.0),
            "Great Barrier is a favorite"
          )
        }
      }
    • 16:36 - Set up your device for test execution

      // Set up your device for test execution
      import XCTest
      import CoreLocation
      
      class LandmarksUITests: XCTestCase {
      
        override func setUp() {
          continueAfterFailure = false
          
          XCUIDevice.shared.orientation = .portrait
          XCUIDevice.shared.appearance = .light
            
          let simulatedLocation = CLLocation(latitude: 28.3114, longitude: -81.5535)
          XCUIDevice.shared.location = XCUILocation(location: simulatedLocation)
        }
        
      }
    • 16:54 - Launch your app with environment variables and arguments

      // Launch your app with environment variables and arguments
      import XCTest
      
      class LandmarksUITests: XCTestCase {
      
        func testLaunchWithDefaultCollection() {
          let app = XCUIApplication()
          app.launchArguments = ["ClearFavoritesOnLaunch"]
          app.launchEnvironment = ["DefaultCollectionName": "Australia 🐨 🐠"]
          app.launch()
      
          app.tabBars.buttons["Collections"].tap()
          XCTAssertTrue(app.buttons["Australia 🐨 🐠"].waitForExistence(timeout: 10.0))
        }
      }
    • 17:04 - Launch your app using custom URL schemes

      // Launch your app using custom URL schemes
      import XCTest
      
      class LandmarksUITests: XCTestCase {
      
        func testOpenGreatBarrier() {
          let app = XCUIApplication()
          let customURL = URL(string: "landmarks://great-barrier")!
          app.open(customURL)
      
          XCTAssertTrue(app.wait(for: .runningForeground, timeout: 10.0))
          XCTAssertTrue(app.staticTexts["Great Barrier Reef"].waitForExistence(timeout: 10.0))
        }
      }
    • 17:12 - Launch your app using custom URL schemes and the system default app

      // Launch your app using custom URL schemes
      import XCTest
      
      class LandmarksUITests: XCTestCase {
      
        func testOpenGreatBarrier() {
          let app = XCUIApplication()
          let customURL = URL(string: "landmarks://great-barrier")!
          XCUIDevice.shared.system.open(customURL)
      
          XCTAssertTrue(app.wait(for: .runningForeground, timeout: 10.0))
          XCTAssertTrue(app.staticTexts["Great Barrier Reef"].waitForExistence(timeout: 10.0))
        }
      }
    • 17:13 - Perform an accessibility audit during an automation

      // Perform an accessibility audit during an automation
      import XCTest
      
      class LandmarksUITests: XCTestCase {
        
        func testPerformAccessibilityAudit() {
          let app = XCUIApplication()
          try app.performAccessibilityAudit()
        }
      
      }
    • 0:00 - 서론 및 어젠다
    • Xcode의 UI 자동화는 XCUIAutomation 프레임워크로 구동되고 앱을 종합적으로 테스트할 수 있습니다. Swift Testing 및 XCTest 프레임워크와 함께 작동하여 완전한 앱 테스트 모음을 제공합니다. UI 자동화 테스트는 앱의 사용자 경험, Apple 하드웨어와의 통합, 일반적인 워크플로의 동작을 검증하여 앱 논리 및 데이터 모델에 초점을 맞춘 단위 테스트를 보완합니다. 이 과정은 세 가지 주요 단계로 구성됩니다. 상호작용을 기록한 후 자동으로 코드로 변환됩니다. 다양한 기기, 언어, 지역, 방향에 걸쳐 이러한 상호작용을 재생합니다. 각 UI 테스트 실행에 대한 비디오 녹화본과 결과를 검토합니다. 이러한 자동화를 통해 실제 사용자처럼 앱을 테스트하여 접근성, 언어 지원, 하드웨어 통합을 보장할 수 있습니다. 이 기능은 모든 Apple 플랫폼에서 지원되기 때문에 한 번의 클릭으로 iPhone, iPad, Mac, Apple TV, Apple Watch와 같은 여러 기기에 대한 자동화 테스트를 한 번에 빌드하고 실행할 수 있습니다.

    • 3:58 - UI 자동화 개요
    • UI 자동화는 앱을 실행하고, 버튼을 탭하며, 화면을 탐색하는 등 사용자와의 상호작용을 모방합니다. 앱의 손쉬운 사용 기능을 활용하면 요소에 대한 레이블, 값, 고유 식별자를 제공하여 이러한 작업을 독립적으로 수행할 수 있습니다. Apple의 핵심 가치인 손쉬운 사용은 모든 사람들이 앱을 사용할 수 있도록 보장하고 UI 자동화를 지원합니다.

    • 6:26 - 앱 자동화 준비하기
    • 앱 자동화를 준비하려면 여러 단계가 필요합니다. 먼저, 앱 요소에 손쉬운 사용 식별자를 추가합니다. 이러한 식별자는 SwiftUI, UIKit 또는 AppKit으로 작성된 고유한 레이블로, 자동화 툴이 앱의 특정 부분을 인식하고 상호작용하는 데 도움이 됩니다. 이러한 태그는 지역화된 문자열 또는 동적 콘텐츠가 있는 요소에 특히 유용하고 전체 앱 내에서 설명적이고, 정적이며, 고유해야 합니다. 다음으로, Accessibility Inspector를 사용하여 앱의 손쉬운 사용 기능을 빠르게 검토합니다. 이 툴은 손쉬운 사용 문제를 식별하고 수정하여 앱이 자동화에 적합하도록 준비하는 데 도움이 됩니다. Accessibility Inspector를 사용하면 각 뷰의 손쉬운 사용 속성을 보고 수정할 수 있어 보조 기술 및 자동화 스크립트 모두에서 앱을 더 유용하게 사용할 수 있습니다. 마지막으로 Xcode 프로젝트에 새로운 UI 테스트 대상을 추가합니다. 이 타깃은 자동화 코드를 저장하기 위한 전용 공간을 제공합니다. 타깃이 설정되면 앱과의 상호작용을 기록하여 자동으로 Swift 코드로 변환됨으로써 자동화 프로세스를 간소화합니다.

    • 11:32 - 상호작용 기록하기
    • Xcode와 시뮬레이터에 표시된 Landmarks 샘플 프로젝트는 호주로 떠나는 가상 휴가를 계획하는 방법을 보여 줍니다. UI 녹화는 앱 내 상호작용을 코드로 캡처합니다. 이 예제에서는 새로운 컬렉션을 추가하고, 이름을 ‘Max의 호주 모험’으로 바꾸며, Great Barrier Reef 및 Uluru와 같은 랜드마크로 채웁니다. 기록을 중단한 후 이 예제에서는 생성된 코드를 검토하고, 적절한 UI 쿼리를 선택하며, XCTest를 사용하여 검증을 추가하여 앱의 기능을 보장합니다. 그런 다음 테스트를 재실행하여 컬렉션 생성과 랜드마크 추가를 성공적으로 검증합니다. 특정 기기 상태를 설정하고, 위치를 시뮬레이션하며, 손쉬운 사용 기능 감사를 수행하여 테스트를 더욱 향상시킬 수 있습니다.

    • 17:30 - 여러 구성에서 다시 재생하기
    • Xcode Cloud를 사용하면 다양한 언어 및 기기뿐만 아니라, 데스크 및 클라우드의 다양한 구성으로 자동화된 앱 테스트를 수행할 수 있습니다. 테스트 계획은 테스트를 구성하고, 시스템 설정을 지정하며, 속성을 관리합니다. 구성을 통해 긴 문자열이나 우횡서 스크립트를 사용하는 언어를 포함하여 특정 로케일에서 테스트할 수 있습니다. Xcode Cloud는 클라우드에서 테스트를 실행하여 실패한 부분의 비디오와 스크린샷을 저장하여 검토합니다. 전체 팀원들이 실행 기록, 로그, 결과를 볼 수 있어 쉽게 협업 및 원격 모니터링을 할 수 있습니다. 고급 구성 및 자세한 내용은 개발자 문서에서 확인할 수 있습니다.

    • 20:54 - 비디오 및 결과 검토하기
    • Xcode 테스트 보고서는 테스트 결과를 분석하기 위한 포괄적인 도구를 제공합니다. 실패한 테스트 실행을 식별하면 비디오 녹화본과 자세한 설명을 볼 수 있습니다. 보고서는 비디오에 UI 상호작용을 오버레이하고 빠른 탐색을 위한 실패 다이아몬드가 있는 타임라인을 포함합니다. 실패 지점에서 현재 UI 요소를 보고, 코드 제안을 받으며, 테스트 코드를 직접 편집할 수 있습니다. 수정한 후 테스트를 재실행할 수 있고 보고서를 통해 다양한 언어와 레이아웃에서 기능을 검증하여 궁극적으로 앱 품질과 손쉬운 사용 기능을 향상시킬 수 있습니다.

    • 24:16 - 다음 단계
    • 단위 테스트 및 Swift 테스트에 대한 자세한 내용은 WWDC24의 ‘Swift Testing 소개’ 세션을 참조하고 질문이나 피드백이 있으면 개발자 포럼을 방문하세요.

Developer Footer

  • 비디오
  • WWDC25
  • 기록, 재생 및 검토: Xcode로 UI 자동화
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝 및 AI
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드(영문)
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • News Partner Program(영문)
    • Video Partner Program(영문)
    • Security Bounty Program(영문)
    • Security Research Device Program(영문)
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    Apple Developer 앱 받기
    Copyright © 2025 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침