로컬 실행과 실패 테스트 단독 실행은 통과하지만, 원격 맥 CI를 반복 실행할 때만 무작위 실패가 발생합니다.

이번 주에는 전체 병렬 실행을 끄지 말고 공유 상태와 파일, 포트, 키체인, 시뮬레이터 자원을 먼저 격리하십시오. 그래도 남는 충돌만 해당 테스트 범위에 .serialized를 적용한 뒤, 깨끗한 원격 맥 작업 공간에서 병렬 실행을 다시 검증해야 합니다.

01

이 글을 읽어야 하는 사람

엑스코드 프로젝트에서 엑스씨테스트를 Swift Testing으로 옮긴 뒤 테스트 순서가 바뀌면서 실패가 나타난 개발자를 위한 글입니다. 원격 맥 테스트 파이프라인과 결과 수집을 담당하는 데브옵스·테스트 엔지니어도 대상입니다.

테스트를 고칠지, 일부만 직렬화할지, 전용 노드를 추가할지 결정해야 하는 연구개발 플랫폼 책임자에게도 필요한 판단 기준을 제공합니다.

마지막 업데이트: 2026년 9월 6일. 병렬 실행, .serialized, 마이그레이션과 테스트 결과 동작은 애플의 Swift Testing 공식 문서, 병렬 실행 문서, 테스트 결과 문서를 기준으로 확인했습니다.

02

먼저 실패를 네 갈래로 분류하십시오

Swift Testing은 기본적으로 테스트 병렬 실행을 지원합니다. 그러나 무작위 실패가 곧 프레임워크 결함을 뜻하지는 않습니다. 프로세스 안의 테스트 병렬 실행, 엑스씨테스트의 병렬 실행, CI 작업 동시 실행, 여러 러너의 동시 실행은 서로 다른 층입니다. 한 설정으로 모두 설명하면 원인을 놓칩니다.

테스트 작성자가 수집할 증거

고정된 커밋, 같은 엑스코드 도구 모음, 같은 테스트 진입점을 사용하십시오. 매 실행마다 다음 정보를 보관해야 합니다.

  • 실패한 테스트 이름과 실행 순서
  • 테스트 결과 묶음과 실패 시점
  • 노드의 메모리 압박, 디스크 여유 공간, 백그라운드 작업
  • 같은 실패 테스트를 단독 실행했을 때의 결과

연속 반복에서 병렬 실행일 때만 실패하고 단독 실행에서는 통과한다면 동시성 관련성을 의심할 수 있습니다. 반대로 깨끗한 환경에서도 같은 테스트가 계속 실패하면 안정적인 코드 오류일 가능성이 더 큽니다. 결과 묶음 보관 방식은 엑스코드 테스트 결과 해석 안내에 맞추어 팀의 증거 형식을 통일하십시오.

Swift Testing이 왜 CI에서만 무작위로 실패합니까?

CI에서는 로컬과 달리 여러 작업이 같은 작업 공간, 캐시, 포트 또는 키체인을 공유할 수 있습니다. 테스트 순서가 달라지는 것만으로도 전역 상태가 이전 테스트의 값을 읽을 수 있습니다. 먼저 실행 계층과 공유 자원을 분리해야 하며, 곧바로 전체 병렬 실행을 끄는 방식은 원인을 숨길 수 있습니다.

03

첫 번째 단계: 테스트 내부의 공유 상태를 없애십시오

테스트 작성자의 첫 책임은 테스트 간 상태 오염을 제거하는 일입니다. 다음 항목을 코드 검색 대상으로 삼으십시오.

  • 전역 변수와 정적 캐시
  • 싱글턴이 보관하는 사용자 세션
  • 테스트 사이에 재사용되는 객체
  • 알림 수신기와 비동기 작업
  • 설정값을 한 번 쓰고 다음 테스트가 그대로 읽는 코드

각 테스트가 필요한 픽스처를 직접 생성하도록 바꾸십시오. 설정과 정리 로직이 테스트가 끝나기 전에 실제로 완료되는지도 확인해야 합니다. 비동기 작업을 시작한 뒤 테스트가 먼저 끝나면 다음 테스트와 자원 경쟁이 생길 수 있습니다.

엑스씨테스트에서 Swift Testing으로 옮기는 공식 안내의 구조를 참고하되, 자동 변환만 믿지 마십시오. 마이그레이션 뒤에는 테스트 격리 조건이 유지되는지 별도로 검토해야 합니다.

수정 후에는 임의 순서 실행과 반복 실행을 사용하십시오. 실패가 사라졌다는 사실보다, 테스트가 어떤 상태를 소유하는지 설명할 수 있는지가 더 중요합니다. 테스트 작성자는 수정된 픽스처와 재현 기록을 CI 담당자에게 넘기고, 재현되지 않는 상태에서 작업을 끝내지 않아야 합니다.

04

두 번째 단계: 파일과 시스템 자원을 테스트별로 나누십시오

애플리케이션 엔지니어는 코드 상태만 보지 말고 운영체제 자원까지 확인해야 합니다. 특히 다음 다섯 가지가 자주 충돌합니다.

  • 고정된 임시 폴더와 데이터베이스 파일
  • 고정된 네트워크 포트
  • 사용자 기본 설정
  • 키체인 항목
  • 알림 수신기와 시뮬레이터 상태

테스트마다 고유한 임시 디렉터리와 데이터베이스 이름을 만들고, 포트는 실행 시 할당받도록 바꾸십시오. 키체인은 삭제부터 하지 말고 테스트 전용 항목 이름과 정리 책임을 먼저 정의해야 합니다. 삭제가 필요한 경우에는 어떤 개발 계정과 인증 항목에 영향을 주는지 기록하고, 실패 시 복구 절차를 남겨야 합니다.

시뮬레이터나 사용자 인터페이스 테스트는 프로세스 안의 Swift Testing 병렬 실행과 별개로 다루십시오. 시뮬레이터 한 대를 여러 작업이 동시에 조작하면 코드가 안전해도 충돌할 수 있습니다. 이 경우 테스트를 무조건 직렬화하기보다 시뮬레이터와 작업 공간을 작업 단위로 분리하는 편이 낫습니다.

주의: 캐시 삭제, 키체인 초기화, 전역 병렬 실행 해제는 진단 수단이지 기본 복구책이 아닙니다. 적용 범위와 되돌리는 조건을 티켓에 함께 남기십시오.

05

.serialized는 범위를 좁혀 적용하십시오

Swift Testing에서 일부 테스트만 병렬 실행을 끄려면 어떻게 해야 합니까?

공유 자원을 당장 분리할 수 없는 테스트 범위에만 .serialized를 적용하십시오. Apple 문서에 따르면 이 특성은 테스트 모음이나 매개변수화된 테스트에 제한적인 직렬 실행을 지정하는 용도로 제공됩니다. 세부 의미는 .serialized 공식 설명공식 구현 코드에서 확인할 수 있습니다.

.serialized는 테스트 함수와 모음 중 어디에 붙여야 합니까?

판단 기준은 공유 자원의 소유 범위입니다. 한 테스트만 외부 자원을 사용한다면 가장 좁은 범위에 적용하십시오. 여러 테스트가 같은 상태를 공유한다면 해당 모음에 적용하는 편이 안전합니다. 매개변수화된 테스트가 같은 자원을 함께 사용한다면 매개변수 단위의 병렬 실행도 따로 확인해야 합니다.

.serialized 적용 뒤에도 실패가 사라졌다고 바로 성공으로 판정하지 마십시오. 직렬화가 원인을 가리는 것인지, 실제로 자원 충돌을 제거한 것인지 확인해야 합니다. 티켓에는 다음 세 항목을 남기십시오.

  • 직렬화한 테스트와 보호하는 자원
  • 병렬 실행을 복구할 수 없는 현재 제약
  • 자원 격리 후 .serialized를 제거할 조건
06

엑스씨테스트와 Swift Testing의 경계를 확인하십시오

Swift Testing과 엑스씨테스트를 함께 사용하면 병렬 실행에 영향을 줍니까?

두 프레임워크는 한 프로젝트 안에서 함께 사용할 수 있습니다. 다만 어떤 테스트 대상이 어떤 프레임워크로 실행되는지, 테스트 계획과 스킴이 어떤 설정을 전달하는지는 별도로 확인해야 합니다. Swift Testing의 설계 문서엑스코드 테스트 대상 구성 안내를 기준으로 대상을 나누어 보십시오.

마이그레이션 담당자는 다음을 대조해야 합니다.

  • Swift Testing 모음과 엑스씨테스트 클래스의 목록
  • 로컬과 CI의 테스트 계획
  • 스킴에서 선택된 테스트 대상
  • 명령줄에서 전달되는 병렬 실행 관련 설정
  • 여러 CI 작업이 같은 러너를 사용하는지 여부

엑스씨테스트의 병렬 실행과 Swift Testing의 프로세스 내 병렬 실행을 같은 문제로 취급하지 마십시오. 특정 모음에서만 실패한다는 증거가 있을 때만 그 범위에 .serialized를 적용하십시오. 전체 테스트 대상에 직렬화를 걸면 파이프라인은 조용해질 수 있지만, 공유 상태를 고치는 작업은 뒤로 밀립니다.

07

원격 맥 노드에서 재현하고 판정하십시오

원격 맥에서 Swift Testing 동시성 문제를 어떻게 재현합니까?

첫 실행 전에 커밋, 엑스코드 도구 모음, 테스트 계획, 환경 변수를 고정하십시오. 그다음 아래 순서로 비교하십시오.

  1. 깨끗한 복제본을 만들고 기존 작업 공간을 사용하지 않습니다.
  2. 별도 파생 데이터 경로와 테스트용 임시 디렉터리를 지정합니다.
  3. 병렬 실행과 부분 직렬화 실행을 같은 커밋으로 각각 수행합니다.
  4. 실패 테스트를 단독 실행하고 결과 묶음과 노드 로그를 보관합니다.
  5. 노드를 재시작한 뒤 같은 조건으로 다시 실행합니다.
  6. 다른 CI 작업이 없는 전용 노드에서 결과를 대조합니다.

이 과정에서 병렬 실행에서만 실패하면 테스트 격리 작업을 우선합니다. 깨끗한 전용 노드에서도 실패하면 코드나 테스트 계획을 다시 봐야 합니다. 특정 노드에서만 실패하면 백그라운드 작업, 디스크 상태, 로그인 세션, 공유 작업 공간을 조사하십시오.

VpsMesh의 원격 맥 CI 환경을 사용할 때도 같은 커밋과 같은 테스트 계획을 유지해야 비교가 성립합니다. 노드가 항상 켜져 있다는 이유만으로 깨끗한 테스트 환경이 보장되지는 않습니다. 작업 종료 뒤 파생 데이터와 임시 파일을 정리하고, 다음 작업이 이전 키체인과 설정을 물려받지 않는지 확인하십시오.

08

플랫폼 책임자의 선택 기준

아래 표는 세 가지 대응을 결정할 때 사용할 수 있는 판단 도구입니다.

조건 우선 선택 중단 조건
공유 상태를 코드에서 분리할 수 있음 테스트 리팩터링 후 병렬 유지 반복 실행에서 같은 충돌이 남음
특정 모음만 외부 자원을 공유함 해당 모음만 .serialized 적용 직렬화 범위가 계속 넓어짐
여러 작업이 노드 자원을 점유함 작업 공간과 전용 원격 맥 노드 분리 전용 노드에서도 코드 재현
실패 원인을 구분할 증거가 없음 결과 묶음과 노드 로그 수집 동일 조건 기록이 누락됨

전체 병렬 실행 해제는 임시 회귀 조치로만 사용하십시오. 적용한다면 복구 담당자, 재검토 날짜, 병렬 실행을 다시 켤 조건을 함께 정해야 합니다. 전용 노드가 필요한 경우에는 맥 미니 서버 운영과 개인정보 보호 기준도 함께 검토할 수 있습니다.

장기적으로 안정적인 고정 작업이 필요하고 물리 장치나 지속적인 로컬 저장소가 중요하다면 맥 미니를 직접 운영하는 편이 맞을 수 있습니다. 반대로 이번 문제처럼 특정 커밋의 병렬 실패를 반복 재현하거나 단기간 별도 노드가 필요한 경우에는 구매 장비가 과할 수 있습니다.

현재 컴퓨터 한 대에서만 시험하면 로컬 통과라는 착시에 머물기 쉽고, 공유 노드를 계속 사용하면 다른 파이프라인의 파일과 키체인이 섞일 수 있습니다. 독립 원격 맥을 빌려 같은 커밋을 병렬과 부분 직렬 조건으로 나누어 확인하면 코드 문제와 노드 문제를 분리하기 쉽습니다. 이런 임시 검증과 재현용 환경에는 VpsMesh의 맥 렌탈이 더 유연한 선택입니다. 단, 장기간 고정 부하와 물리 인터페이스가 필요한 운영이라면 직접 구매한 맥 미니가 더 적합합니다.