Meet Swift Testing - WWDC24
뛰어난 사용자 경험을 제공하려면 품질과 안전성이 매우 중요.

Swift Testing은 새로운 오픈소스 패키지로 Swift 동시성 및 매크로 같은 최신 기능을 도입함.
Linux와 Windows 등 모든 주요 플랫폼을 지원함.

@Test가 Swift Testing에서 함수가 테스트임을 나타냄.
async or throws를 사용할 수 있으며 경우에 따라서 Actor로 격리 가능함.

#expect는 매크로로 일반 표현식과 언어 연산자를 허용함.
테스트가 실패할 경우에는 코드와 표현식에 대한 값을 캡처함.

테스트가 실패한 경우 #expect에 전달된 표현식에 대한 세부 정보가 하위 값과 함께 표시됨.

#expect는 매우 유연해서 연산을 수행할 수 있음.
테스트를 위해서 XCTest에 존재하던 전문적인 API를 별도로 학습하지 않아도 됨.

테스트가 실패해 조기종료를 원하는 경우에는 try #require를 사용할 수 있음.
표현식이 false일 경우에 테스트가 실패하고 더 이상 진행되지 않음.

선택적으로 값을 언래핑하고 nil일 경우 테스트를 중지하는 것을 원하는 경우에 유용.

Trait은 여러가지를 할 수 있음.
테스트에 대한 설명 정보를 추가하거나 테스트 실행 시기 또는 실행 여부를 커스터마이징하거나
테스트 동작 방식을 수정할 수 있음.

단순하게 테스트 디스플레이에 표시될 이름을 추가하는거 외에도 정보를 추가하거나 태그를 추가할 수도 있음.
특정 조건에서만 테스트를 실행하려면 Trait을 제어할 수도 있음
일부 테스트는 실제 작동 방식에 영향을 줌. (타임아웃이나 직렬화하는 등)

구조체로 묶어서 그룹화도 가능함. (Suite)

@Suite 속성으로 명시적으로 주석을 달 수도 있음.
테스트 함수 또는 @Suite를 포함하는 모든 타입은 암시적으로 @Test로 간주함.
각 테스트 전후에 init 또는 deinit으로 로직을 수행함. (setup, teardown 로직 대체)
각 @Test 메서드마다 별도로 인스턴스가 매번 생성되어서 의도하지 않은 공유 상태를 방지함

위로 뺴도 각각의 메서드에서는 항상 새롭게 생성되므로 문제가 되지 않음.

Swift Concurrency랑 통합되며
expeaction 매크로도 async await을 사용할 수 있고
Swift 언어내 내장된 연산자를 사용하며 자세한 실패 결과를 확인 가능함
@Suite는 그룹을 통해 명시적으로 분리해서 관리할 수 있음.

테스트 실행 시기를 제어하고
공통점이 있는 특성을 통합하고
테스트를 두 번 이상 반복하는 작업에 대해서 논의

일부 테스트는 특정 상황에서만 실행되어야 하는데, 이러한 경우에 enabled(if: )를 활용할 수 있음
조건이 false라면 테스트를 건너 뛰는 것으로 판단함.

이번에는 테스트가 절대로 실행되지 않도록 하고 싶은 경우도 존재.
이 경우에는 .disabled(...) 특성을 사용할 수 있음.
테스트 함수 자체를 주석처리하는 다른 기법보다 선호되는데 컴파일 된 내부 코드를 확인하기 때문
disalbed는 메시지를 포함하는걸 허용하는데 CI 시스템에서 가시성을 위해 표시할 수 있음.

테스트가 비활성화되는 이유는 버그 추적 시스템에서 추적되는 문제 때문인 경우가 많음.
주석 외에도 .bug 특성을 다른 특성과 함께 포함시켜 URL로 관련 이슈를 참고할 수 있음.

#available보다는 @available를 사용하자.
왜냐하면 테스트 라이브러리가 테스트하는 환경의 OS 버전을 알아 알아서 분기해줌.

공통된 특징을 가진 것들에 대해서 서드파티에 있는 것들도 어떻게 연결 시킬 수 있는지를 알아보자.
Swift Testing은 커스텀 가능한 태그 할당을 지원함.
좌측 instpector에서 태그를 그룹별로 모아볼 수 있고, @Suite와 구조체를 통한 그룹화도 가능함.
@Suite를 사용할 경우 태그가 상속되어 각 개별 @Test 함수에서 태그를 삭제해도 됨.

공통점이 있는 테스트에 태그를 연결할 수 있음.
특정 기능이나 유효성을 검사하는 모든 테스트에 태그를 연결할 수 있음
태그를 필터링해서 사용할 수도 있으며 여러 프로젝트에서도 공유할 수 있음.

Swift Testing을 사용할 때는 테스트 Plan에 특정한 이름보다 태그를 포함시키거나 제외하는게 더 좋음.
각 상황에 맞는 가장 적합한 Trait을 사용하기.
모든 시나리오가 태그를 포함할 필요는 없으며, 런타임 조건을 표현하려는 경우에는 앞서 .enabled(if:)가 더 좋음.

매번 다른 인수를 사용해 테스트를 반복하는 것은 매우 유용함.
이런 형태로 사용하면, 중복되는 테스트 없이 관리할 수 있음.

테스트 네비게이터에서 실패한 값들만 별도로 실행할 수도 있음.
매개화된 변수는 반복문을 이용해서 실행되는 단일 테스트와 유사함.

각 인자에 대해서 독립적으로 보이고
디버그 환경에서 개별적으로 재실행할 수 있고
병렬로 실행하여 결과를 더 빨리 얻을 수 있음.


오른쪽 형태의 테스트가 보인다면, 매개화된 테스트를 위해서 독립적으로 사용하는 것이 좋음.
왼쪽 유형의 테스트가 병렬로 처리되어서 결과가 나오는 속도 측면에서 훨씬 좋음.

Swift Testing은 XCTest랑 공통적인 측면도 있지만 아닌 부분도 존재함.


XCTest의 경우에는 Assertion이라고 하고 Swift Testing의 경우에는 #expect 하나만 가지고도 처리 가능함.
XCTest의 여러 테스트 메서드 대신 연산자로 처리가 가능함.

테스트를 중단하는 방법에도 차이가 존재하는데, 코드로 보면 위 처럼 분리됨.

Suite 를 비교하자면 이런 부분들에 차이가 있음.
XCTest보다 Swift Testing이 훨씬 더 간결해짐.

XCTest와 Swift Testing은 하나의 유닛 테스트에 공존할 수 있어서 점진적으로 마이그레이션 가능함.
구조가 유사한 것들의 경우에는 매개변수를 활용해 통합할 수 있음.

UI자동화나 성능테스트를 위한 API는 현재 Swift Testing을 지원하지 않고 objc코드도 지원하지 않음.
Swift Testing이나 XCTest의 코드를 서로 다른 영역에서 호출하지 말것.

Swift testing은 애플 플랫폼이 아닌 다른 곳에서도 동작함!