Showing Posts From

테스트의

자동화 테스트의 실행 시간이 1시간이 넘어갔을 때

자동화 테스트의 실행 시간이 1시간이 넘어갔을 때

자동화 테스트가 1시간 넘어간 날 아침 9시, 빨간 불 출근했다. 슬랙 알림이 12개다. "Test failed after 1h 42m" 젠킨스 파이프라인이 또 터졌다. 1시간 42분 돌다가 실패. 개발자들 머지 블록당했다. PM이 물어본다. "언제 고쳐지나요?" 모르겠다. 일단 커피부터.작년만 해도 20분이었다. 지금은 1시간 반. 테스트 케이스가 늘어날 때마다 시간도 늘었다. 선형적으로. 문제는 명확했다. 직렬 실행. 800개 테스트가 하나씩 돌아간다. 병렬 처리? 없다. 웨이트 타임? 넘친다. time.sleep(5) 가 237군데. 계산해봤다. 237 × 5초 = 1,185초. 20분이 그냥 기다리는 시간이다. 병렬화 시작 점심 먹고 작업 시작했다. 먼저 pytest-xdist 설치. pytest -n 44개 워커로 돌렸다. 기대했다. 1시간 반이면 20분 되겠지. 결과: 1시간 10분. 왜? 테스트 간 의존성. 3번 테스트가 1번 결과를 쓴다. 병렬로 돌면 깨진다. 격리가 안 돼 있었다. 2시간 걸려서 테스트 12개 수정. DB 픽스처를 각 테스트마다 독립적으로. 공유 상태 제거. 다시 돌렸다. pytest -n 8 --dist loadgroup8개 워커. 결과: 35분. 절반 넘게 줄었다. 개발자가 슬랙에 썸즈업 보냈다.웨이트 지옥 탈출 다음은 대기 시간. time.sleep(5) 를 전부 찾았다. 237개. 복붙의 역사다. # Before driver.click() time.sleep(5) assert element.is_displayed()# After driver.click() WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.ID, "result")) )명시적 대기로 바꿨다. 조건 충족하면 바로 넘어간다. 5초 안 기다려도 된다. 평균 대기 시간이 5초에서 1.2초로 줄었다. 237개 × 3.8초 = 900초 절약. 15분이다. 실행 시간: 20분. 1시간 반에서 20분. 4.5배 빨라졌다. 테스트 선택 실행 그런데 문제가 있었다. PR 하나 올릴 때마다 800개 전부 돌린다. API 하나 고쳤는데 UI 테스트까지 돈다. 비효율이다. 테스트 태깅 시작했다. @pytest.mark.api def test_login_api(): pass@pytest.mark.ui def test_login_ui(): pass@pytest.mark.critical def test_payment(): pass파이프라인 3개로 분리.PR: critical만 (120개, 5분) Merge: api + critical (350개, 12분) Nightly: 전체 (800개, 20분)개발자들 피드백 속도가 확 빨라졌다. PR 올리고 5분이면 결과 나온다.여전히 느린 것들 20분도 여전히 길다는 얘기가 나왔다. 프로파일링 돌렸다. pytest-profiling 설치. pytest --profile결과 보고 놀랐다.test_bulk_upload: 3분 22초 (전체의 16%) test_data_migration: 2분 48초 test_report_generation: 2분 15초3개가 8분을 먹는다. 이건 E2E가 아니라 통합 테스트였다. 실제 10만 건 데이터로 돌리고 있었다. 분리했다. 통합 테스트는 nightly만. E2E는 샘플 데이터 100건으로. 실행 시간: 12분. 캐시와 재사용 다음 최적화. 셋업 시간. 매 테스트마다 브라우저 새로 띄운다. 로그인한다. 메인 페이지 간다. 매번. @pytest.fixture(scope="session") def authenticated_session(): driver = webdriver.Chrome() driver.get("https://app.test") login(driver) yield driver driver.quit()세션 스코프 픽스처. 로그인 한 번만 한다. 800번이 1번으로. 단, 조심해야 한다. 상태 오염. 각 테스트 전에 초기화 필요. @pytest.fixture(autouse=True) def reset_state(authenticated_session): authenticated_session.delete_all_cookies() authenticated_session.get("https://app.test/dashboard")효과: 2분 단축. 실행 시간: 10분. 도커 이미지도 캐싱했다. 테스트 환경 띄우는 데 3분 걸렸는데, 레이어 캐싱으로 30초로 줄었다. Flaky 테스트 지옥 빨라지니까 다른 문제가 보였다. 간헐적 실패. Flaky 테스트. 10번 돌리면 1번 실패한다. 병렬 실행하면서 더 자주 보인다. 타이밍 이슈, 레이스 컨디션. pytest --reruns 3 --reruns-delay 1실패하면 3번 재시도. 그런데 근본 해결은 아니다. 진짜 문제를 찾아야 했다. 일주일간 로그 분석.네트워크 타임아웃: 15건 엘리먼트 로드 타이밍: 23건 DB 트랜잭션 충돌: 8건하나씩 고쳤다. 명시적 대기 추가. 리트라이 로직. DB 격리. Flaky 비율: 12% → 2%. 안정화되니까 신뢰도가 올라갔다. 개발자들이 테스트 결과를 믿는다. 비용 계산 최적화 전후 비교했다. Before:실행 시간: 1시간 42분 하루 10회 실행 EC2 비용: 월 200달러 개발자 대기 시간: 하루 17시간After:실행 시간: 10분 하루 30회 실행 (더 자주 돌림) EC2 비용: 월 80달러 (병렬이지만 짧아서) 개발자 대기 시간: 하루 5시간월 120달러 절약. 더 중요한 건 개발자 12시간 절약. 한 달이면 240시간. 10명이면 2,400시간. 돈으로 환산하면 1억 넘는다. 모니터링 대시보드 지표 추적 시작했다. Grafana 대시보드 만들었다. 매일 확인한다.평균 실행 시간 P95 실행 시간 (상위 5% 느린 케이스) Flaky 비율 병렬화 효율 (이론상 시간 대비 실제) 테스트당 평균 시간그래프가 튀면 조사한다. 느린 테스트 주간 리포트. 팀 회의 때 공유. 개발자들이 테스트 성능도 신경 쓰기 시작했다. "이거 테스트 오래 걸리겠는데요?" 미리 물어본다. 문화가 바뀌었다. 다음 목표 10분도 길다. 다음 최적화 계획:테스트 샤딩 (여러 머신에 분산) 스마트 테스트 선택 (변경된 코드만) 시각적 회귀 테스트 병렬화 더 빠른 브라우저 (headless Chrome → Playwright)목표는 5분. PR 피드백 5분 이내. CTO가 물었다. "테스트를 줄일 수는 없나요?" 아니다. 품질은 타협 못 한다. 대신 빠르게 돌린다. 테스트 800개 유지. 실행 시간만 줄인다. 배운 것 1시간 반이 10분 됐다. 10배 빨라졌다. 한 번에 된 게 아니다. 2달 걸렸다. 매주 조금씩. 병렬화가 가장 효과 컸다. 4.5배. 단, 격리가 전제다. 명시적 대기가 두 번째. 불필요한 시간 제거. 15분 절약. 테스트 선택이 세 번째. 전부 돌릴 필요 없다. 상황에 맞게. 프로파일링이 핵심이다. 추측 말고 측정. 데이터로 판단. 지속적 관리가 필요하다. 한 번 최적화하고 끝이 아니다. 매주 모니터링. 가장 중요한 건, 빠른 피드백이 개발 속도를 올린다는 것. 테스트가 느리면 개발자들이 안 돌린다. 빠르면 자주 돌린다. 자동화의 가치는 속도다. 느린 자동화는 가치가 반감된다.오늘도 테스트는 10분 만에 끝났다. 예전엔 점심 먹고 와도 안 끝났는데.