[Swift] Swift Testing 톺아보기

2025. 7. 2. 15:34·Apple/Swift
728x90
반응형

안녕하세요! 피피아노입니다 🎵

 

이번 포스팅에서는 WWDC24에서 발표한 새로운 테스트 도구인 Swift Testing에 대해서 공부를 하고 정리를 해보려고 합니다.

 

Swift Testing은 새로운 오픈 소스 패키지로, Swift 코드를 테스트할 수 있습니다. 테스트를 설명하고 구성하는 기능이 포함되어 있으며, 장애 발생 시 대처를 위한 세부 정보를 제공하고 대규모 코드베이스에 맞게 확장할 수 있습니다.

 

프로젝트에 Swift Testing 도입하기

앱에 대한 테스트를 작성해 본 적이 없다면 먼저 프로젝트에 테스트 번들 대상을 추가해줘야 합니다.

 

File > New > Target을 선택합니다.

 

그런 다음 Test 섹션에서 Unit Testing Bundle을 검색합니다.

Swift Testing은 이제 Xcode 16부터 테스트 시스템의 디볼트 선택이 됩니다.

Swift Testing의 특징

Swift 기능 활용

  • Swift용으로 만들어져 동시성 및 매크로와 같은 최신 기능 도입
  • async/await 및 액터 격리 지원
  • Swift 매크로를 활용한 자세한 실패 결과 제공

크로스 플랫폼 지원

  • Linux와 Windows 등 모든 주요 플랫폼 지원
  • 모든 플랫폼에서 공통 코드베이스 사용
  • XCTest와 달리 플랫폼 간 일관된 동작 보장

오픈 소스

  • GitHub에서 호스팅되는 오픈 소스 프로젝트
  • 공개 기능 제안 프로세스를 통한 커뮤니티 참여

Swift Testing의 핵심 구성 요소

1. @Test - 테스트 함수

Swift Testing의 가장 기본적인 구성 요소는 @Test 속성을 가진 함수입니다.

@Test는 함수가 테스트임을 나타냅니다. 

 

@Test를 추가하면 Xcode가 인식하고 위 사진처럼 옆에 Run 버튼을 표시합니다.

import Testing

@Test func videoMetadata() {
    // 테스트 로직
}

 

@Test는 아래와 같은 특징이 있습니다.

  • 전역 함수, 인스턴스 메서드, 정적 메서드 모두 지원
  • 비동기 함수 및 예외 처리 함수 지원
  • 전역 액터로 격리 가능

2. #expect, #require - 기대치

Swift Testing은 2가지 주요 매크로를 제공합니다.

#expect 매크로

@Test func videoMetadata() {
    let video = Video(fileName: "By the Lake.mov")
    let expectedMetadata = Metadata(duration: .seconds(90))
    #expect(video.metadata == expectedMetadata)
}

#require 매크로

@Test func videoProcessing() async throws {
    let videoLibrary = try await VideoLibrary()
    let video = try #require(await videoLibrary.video(named: "By the Lake"))
    #expect(video.formattedDuration == "0m 19s")
}

 

#expect는 중간에 테스트가 실패해도 나머지 테스트들을 계속 진행하고 #require은 중간에 테스트가 실패하면 테스트가 즉시 중단되며 오류가 발생합니다.

 

매크로의 장점으로는 일반 표현식과 언어 연산자 사용이 가능하며, 실패시 소스 코드와 하위 표현식의 값을 자동으로 캡처합니다.

실패를 하면 빨간색 X 아이콘이 표시되고 에러메세지를 클릭하고 Show를 선택해서 해당 줄에서 잘못된 부분을 자세히 확인할 수 있습니다.

 

#require 매크로를 사용할 수 있는 또 다른 방법은 선택적 값을 안전하게 언래핑하고 값이 nil인 경우 테스트를 중지하는 것입니다. 

3. Traits - 특성

특성을 사용하여 테스트의 동작을 맞춤화할 수 있습니다.

 

예를 들어 테스트에 대한 설명 정보를 추가하거나 테스트 실행 시기 또는 실행 여부를 맞춤화하거나, 테스트 동작 방식을 수정할 수 있습니다.

표시 이름

@Test("Check video metadata") func videoMetadata() {
    // 테스트 로직
}

버그 추적

@Test(.disabled("Due to a known crash"),
      .bug("example.org/bugs/1234", "Program crashes at <symbol>"))
func example() {
    // 버그 URL과 함께 비활성화
}

OS 버전 조건

@Test
@available(macOS 15, *)
func usesNewAPIs() {
    // macOS 15 이상에서만 실행
}

 

4. Suite - 테스트 모음

Suite는 관련 테스트 함수 또는 다른 Suite 그룹화에 사용됩니다.

 

Suite은 @Suite 속성으로 명시적으로 주석을 달 수 있습니다 테스트 함수 또는 @Suites를 포함하는 모든 유형은 암시적으로 @Suite 자체로 간주합니다. Suite은 저장된 인스턴스 속성을 가질 수 있습니다 각 테스트 전후에 init 또는 deinit으로 로직을 수행할 수 있습니다 그리고 별도의 @Suite 인스턴스가 모든 인스턴스 @Test 함수에 대해 별도로 생성되어 의도치 않은 상태 공유를 방지합니다.

struct VideoTests {
    let video = Video(fileName: "By the Lake.mov")

    @Test("Check video metadata") func videoMetadata() {
        let expectedMetadata = Metadata(duration: .seconds(90))
        #expect(video.metadata == expectedMetadata)
    }

    @Test func rating() async throws {
        #expect(video.contentRating == "G")
    }
}

특징

  • 구조체, 액터, 클래스 모두 사용 가능 (구조체 권장)
  • 저장된 인스턴스 속성 지원
  • init/deinit을 통한 setup/teardown 로직
  • 각 테스트마다 별도의 인스턴스 생성으로 상태 분리

고급 기능

태그 시스템

관련 테스트들을 태그로 연결하여 관리할 수 있습니다.

@Suite(.tags(.formatting))
struct MetadataPresentation {
    @Test func rating() async throws {
        // 포맷팅 관련 테스트
    }

    @Test func formattedDuration() async throws {
        // 포맷팅 관련 테스트
    }
}

태그 활용

  • 특정 기능이나 하위 시스템별 테스트 그룹화
  • 테스트 계획에서 포함/제외 설정
  • Test Report에서 필터링
  • 크로스 프로젝트 공유 가능

매개변수화된 테스트

Swift Testing의 핵심 기능 중 하나인 매개변수화된 테스트를 통해 중복 코드를 크게 줄일 수 있습니다.

struct VideoContinentsTests {
    @Test func mentionsFor_A_Beach() async throws {
        let videoLibrary = try await VideoLibrary()
        let video = try #require(await videoLibrary.video(named: "A Beach"))
        #expect(!video.mentionedContinents.isEmpty)
        #expect(video.mentionedContinents.count <= 3)
    }

    @Test func mentionsFor_By_the_Lake() async throws {
        let videoLibrary = try await VideoLibrary()
        let video = try #require(await videoLibrary.video(named: "By the Lake"))
        #expect(!video.mentionedContinents.isEmpty)
        #expect(video.mentionedContinents.count <= 3)
    }
    // ... 더 많은 반복적인 테스트들
}

기존에는 이렇게 코드를 작성했었다면, 매개변수화된 테스트를 사용하면 아래처럼 코드를 작성할 수 있습니다.

struct VideoContinentsTests {
    @Test("Number of mentioned continents", arguments: [
        "A Beach",
        "By the Lake",
        "Camping in the Woods",
        "The Rolling Hills",
        "Ocean Breeze",
        "Patagonia Lake",
        "Scotland Coast",
        "China Paddy Field",
    ])
    func mentionedContinentCounts(videoName: String) async throws {
        let videoLibrary = try await VideoLibrary()
        let video = try #require(await videoLibrary.video(named: videoName))
        #expect(!video.mentionedContinents.isEmpty)
        #expect(video.mentionedContinents.count <= 3)
    }
}

매개변수화된 테스트의 장점

  • 각 인수별로 독립적인 결과 확인 가능
  • 실패한 인수만 선택적으로 재실행 가능
  • 병렬 실행을 통한 성능 향상
  • 코드 중복 제거 및 유지보수성 향상

감사합니다.

 

잘못된 내용이 있거나 더 좋은 내용 피드백은 언제나 환영합니다!

궁금하신 부분은 댓글로 질문 부탁드립니다!

728x90
반응형

'Apple > Swift' 카테고리의 다른 글

[Swift] Multipeer Connectivity 톺아보기  (3) 2025.08.23
[Swift] suffix()로 인한 시간 초과 문제 해결하기  (8) 2025.06.27
[Swift] Foundation Models Framework  (6) 2025.06.22
[Swift] Core ML과 MFCC를 활용한 감정 추론  (7) 2025.05.14
[Swift] Tuist 살펴보기  (0) 2025.04.27
'Apple/Swift' 카테고리의 다른 글
  • [Swift] Multipeer Connectivity 톺아보기
  • [Swift] suffix()로 인한 시간 초과 문제 해결하기
  • [Swift] Foundation Models Framework
  • [Swift] Core ML과 MFCC를 활용한 감정 추론
P_Piano
P_Piano
Apple 생태계 개발자가 되기 위한 학습과 경험의 기록
    반응형
    250x250
  • P_Piano
    피피아노의 개발 일지
    P_Piano
  • 전체
    오늘
    어제
    • 분류 전체보기 (211) N
      • Apple (129) N
        • iOS (22)
        • visionOS (4)
        • Swift (69) N
        • UIKit (2)
        • SwiftUI (24)
        • RxSwift (2)
        • Xcode (5)
      • C언어 (5)
      • C++ (8)
      • Dart (1)
      • Python (3)
      • JavaScript (17)
      • Git (1)
      • CS (39)
        • 디자인 패턴 (6)
        • 네트워크 (20)
        • 운영체제 (8)
        • Database (5)
        • 자료구조 (0)
      • IT 지식 (2)
      • IT 뉴스 (4)
      • 출처 표기 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Apple
    Initializers
    swiftUI
    제어문
    티스토리챌린지
    자바스크립트
    클래스
    연산자
    Xcode
    UIKit
    변수
    운영체제
    코딩테스트
    combine
    네트워크
    함수
    배열
    스위프트
    옵셔널
    Vision Pro
    프로세스
    프로그래머스
    오블완
    비동기
    visionOS
    디자인패턴
    SWIFT
    프로퍼티 래퍼
    이니셜라이저
    ios
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
P_Piano
[Swift] Swift Testing 톺아보기
상단으로

티스토리툴바