왜 녹색 CI가 시스템이 작동한다는 의미는 아닐까
Source: Dev.to
사례 연구: TypeScript 마이그레이션이 테스트 실행 시간을 두 배로 늘린 경우 — 실패는 전혀 없었습니다
CI는 초록색이었습니다. 테스트는 통과했습니다. PR은 머지되었습니다.
시스템은 깨졌지만 로그에는 아무것도 나타나지 않았습니다.
테스트 프로젝트를 JavaScript에서 TypeScript로 마이그레이션한 뒤, CI 실행 시간이 거의 두 배가 되었습니다. 실패도 없고 오류도 없었습니다. 단지… 느려졌을 뿐이죠. 저는 이것이 일반적인 TypeScript 컴파일 오버헤드라고 생각하고 넘어갔습니다—우연히 말이죠.
증상
마이그레이션이 거의 끝날 무렵, 원본 .js 파일들을 삭제하기 시작했을 때 테스트 개수가 거의 절반으로 줄어들었습니다:
- 이전: 약 240개 테스트
- 이후: 약 120개 테스트
그 숫자는 말이 안 되었습니다. 저는 테스트를 삭제한 것이 아니라 이미 없어야 할 오래된 JavaScript 파일만 삭제했을 뿐이었습니다.
원인
Playwright가 .spec.js 와 .spec.ts 파일을 동시에 잡아들였습니다. 스위트에 있는 모든 테스트가 두 번씩 실행되었습니다—동일한 어설션, 동일한 설정, 동일한 정리—경고 하나 없이 조용히 중복 실행되었습니다.
가장 안 좋은 점은 낭비된 시간 자체가 아니라 CI가 상황을 개선되는 것처럼 보이게 만든 것이었습니다. 실행 시간이 점차 상승했는데, 이는 “마이그레이션 후 정상적인 속도 저하”로 해석되었습니다. 저는 증상에 대한 그럴듯한 이야기가 있었기 때문에 더 이상 살펴보지 않았습니다.
playwright.config.ts에 명시적인 testMatch가 없었습니다. Playwright의 기본 glob 패턴이 .js와 .ts 파일을 모두 매치하기 때문에 모든 파일을 잡아들인 것이었습니다.
해결 방법
// playwright.config.ts
export default defineConfig({
// …
testMatch: ['**/*.spec.ts'],
});
testMatch 라인을 추가함으로써 중복 실행을 멈출 수 있었습니다.
교훈
-
CI는 실행을 검증할 뿐, 정확성을 검증하지는 않는다. 초록색 CI는 실행 중에 충돌이 없었다는 의미일 뿐이며, 올바른 테스트가 올바른 수량과 가정으로 실행됐다는 것을 보장하지 않습니다.
-
CI에 간단한 테스트 카운터를 도입했다면 이 차이를 잡아낼 수 있었을 것입니다. 이제 파이프라인은 테스트 개수가 기대값과 다르면 명시적으로 실패합니다.
-
테스트 시스템의 대부분 문제는 실패로 나타나지 않습니다. 대신 다음과 같이 나타납니다:
- 중복 실행
- 조용한 성능 저하
- 테스트 변경 없이 러너 동작 변화
그리고 이러한 문제들은 알림이 없습니다. 왜냐하면 우리는 이를 위해 설계하지 않았기 때문입니다.
실패 시그니처
- CI 초록색
- 실행 시간 두 배
- 테스트 개수 두 배
- 경고 없음
숨겨진 가정은 “CI 실행이 느려졌다면 마이그레이션 후 정상적인 오버헤드일 것”이라는 것이었습니다. 실제로는 러너가 몇 주 동안 두 배의 작업을 조용히 수행하고 있었던 것이었습니다—경고 하나 없이.
테스트 자동화에서의 조용한 실패 시리즈 중 일부
전체 프로젝트 (API + UI + E2E + CI + AI 엔드포인트): GitHub