자동화 테스트는 역사적으로 검사의 속도를 높이고 인적 요소를 줄이겠다는 아이디어로 시작되었으나, 빠르게 자동 테스트가 매번 실행 시 다르게 동작하는 경우가 많다는 것이 문제로 드러났습니다. 반복 가능성(repeatability)과 결정성(determinism)은 효과적인 자동 테스트의 기본 품질 요구 사항 중 하나로, 동일한 조건에서 항상 동일한 결과를 가져야 합니다.
문제는 암묵적 의존성에서 시작됩니다: 불안정한 테스트 데이터, 비동기화된 환경, 병렬 프로세스 또는 외부 서비스로 인해 발생합니다. 이로 인해 flaky 테스트가 발생하여 결과를 예측할 수 없게 됩니다.
해결책은 실행 환경에 대한 엄격한 제어, 테스트의 격리, 목(Mock)/스텁(Stub) 객체, 정적 데이터 및 재현 가능한 시나리오(예: 각 테스트 전에 데이터베이스를 정리하고 준비)를 중심으로 세워집니다.
주요 특징:
CI에서만 flaky 테스트가 발생하고 로컬에서는 모두 안정적일 경우 어떻게 해야 하나요?
이는 거의 항상 환경의 차이와 관련이 있습니다: 의존성 버전, 인프라의 속도, 병렬성, 운영 체제 설정 또는 테스트 실행 순서와 관련이 있습니다. 해결책은 CI 환경을 개발 머신(도커, 동일한 시드 값, 테스트에서 setUp/tearDown 설정)과 최대한 비슷하게 만드는 것입니다.
데이터가 데이터베이스에서 가져오면 파라미터화된 테스트를 완전히 결정적이라고 할 수 있습니까?
아니요. 데이터가 기본적으로 같더라도 데이터베이스는 테스트 간이나 릴리즈 간에 변경될 수 있습니다. 진정한 결정성을 위해서는 각 테스트에서 데이터를 명시적으로 준비하고 정리해야 합니다.
요소 로딩을 기다리기 위해 sleep을 사용하면 UI 테스트의 불안정성을 해결할 수 있을까요?
아니요. Sleep은 문제를 단지 숨기고 테스트 실행 속도를 늦춥니다. 특정 조건을 기다리는 명시적 대기(Explicit Waits)를 사용하는 것이 바람직합니다.
프로젝트에서 수동 테스트 후 아무도 정리하지 않은 스탠드에서 UI 테스트를 실행했습니다. 몇 번의 밤마다 테스트는 "무작위" 오류와 함께 실패했습니다. 팀은 테스트에 sleep을 추가하고 flaky 문제를 무시했습니다.
장점:
단점:
성숙한 DevOps 엔지니어의 등장 이후 팀은 테스트 데이터를 초기화 및 리셋하는 스크립트를 구현하고, 불안정한 통합을 위해 mock 서비스를 추가하며 테스트를 컨테이너에서 실행하게 되었습니다. flaky 테스트는 거의 사라졌습니다.
장점:
단점: