테스트의 재실행(retry) 메커니즘은 테스트 파이프라인의 안정성을 높이고 flaky 자동 테스트와 싸우기 위해 도입되지만, 신중한 접근이 필요하다.
질문의 역사
임시 인프라 문제나 flaky 오류를 해결하기 위한 workaround로 등장했으며, 이는 애플리케이션 오류(불안정한 환경, 네트워크 문제, API의 우연한 타임아웃)와 관련이 없다. 현재 많은 CI/CD 시스템은 내장된 retry를 지원한다.
문제
과도하거나 통제되지 않는 retry는 실제 버그를 숨기거나 오류를 "그냥 일시적인 현상"으로 바꿀 수 있다. 잘못된 긍정적 결과가 발생할 수 있다: 테스트는 통과한 것 같지만 여전히 버그가 존재한다.
해결책 불안정한 또는 외부 의존 테스트에 대해서만 retry를 포함시키고, 태그나 마커를 사용하라. 고정된 재실행 한도(1-2회). 실패 및 재실행 성공에 대한 모든 로그를 기록하여 실패 원인을 분석하라.
import pytest @pytest.mark.flaky(reruns=2, reruns_delay=5) def test_external_api(): # API의 불안정성으로 인해 실패할 수 있는 테스트 ...
주요 특징:
파이프라인의 모든 자동 테스트를 재실행할 수 있나요?
이는 나쁜 관행이다: 실제 버그와 테스트의 설계 문제를 모두 숨긴다. Retry는 특정 종류의 테스트에 대한 최후의 수단이다.
테스트가 3번 재실행한 후에도 실패하면 어떻게 해야 하나요?
실행을 중단하고 불안정성/조사를 위해 버그를 열라 — 그렇게 tricky 오류가 드러나며 리팩토링이 필요하다.
테스트가 두 번째 시도에서 통과하면 모든 것이 괜찮은가요?
아니요, 유일하게 바람직한 상태는 첫 번째 시도에서 안정적으로 통과하는 것이다. 두 번째 시도에서의 통과는 문제의 지표(프레이키 또는 인프라 문제)다.
모든 파이프라인에 대해 Jenkins에서 글로벌 retry를 두 번 실행하도록 설정했다. 한 달 후, 코드의 race condition으로 인한 버그가 나타났고, 팀은 "품질이 괜찮다"고 생각했다. 제품은 같은 버그로 인해 프로덕션에서 갑자기 실패하기 시작했다.
장점:
단점:
외부 API와 관련된 테스트 카테고리에 대해서만 retry를 설정했다(태그 기반). 나머지 테스트는 철저히 한 번의 실행만으로 통과한다. 팀은 로그를 기반으로 조사하고 반복적인 실패를 기록한다.
장점:
단점: