본문에서는 Capybara, Cuprite, Puma, Sequel을 통합하여 스크린샷 자동화 시스템을 구축하는 상세한 과정을 다룹니다.
1. Capybara 및 Cuprite 설정
Capybara의 기본 드라이버를 :cuprite로 설정하고, Capybara::Cuprite::Driver.new를 통해 브라우저 창 크기([1200, 800]), 브라우저 타임아웃(15초), base_url(http://localhost:#{PORT}) 등을 지정합니다. 이는 실제 브라우저 환경에서 테스트를 실행하기 위한 필수적인 초기 설정입니다.
2. 별도 서버 스레드 운영 및 동기화
Cuprite는 실제 브라우저를 사용하므로, 애플리케이션 서버는 테스트와는 별개의 스레드 또는 프로세스에서 실행되어야 합니다.
-
Puma 서버 설정:
puma/cli를 사용하여 Puma 서버를-t 1:1옵션으로 단일 스레드/프로세스로 제한하고,tcp://localhost:#{PORT}에 바인딩합니다. -
스레드 분리:
Thread.new를 통해 Puma 서버를 별도 스레드에서 시작합니다. -
부팅 동기화:
Queue를 사용하여 서버가 완전히 부팅될 때까지 메인 스레드가 대기하도록 동기화 메커니즘을 구현합니다.server.launcher.events.on_booted { queue.push(nil) }을 통해 서버 부팅 완료 신호를 보냅니다.
3. Sequel을 활용한 데이터베이스 트랜잭션 관리
rack-test와 달리 Cuprite 환경에서는 테스트 스레드와 서버 스레드가 동일한 데이터베이스 연결을 공유해야 하는 복잡성이 발생합니다. Ubicloud는 Sequel을 사용하여 이를 해결합니다.
-
단일 연결 강제:
ENV["SHARED_CONNECTION"] = "1"환경 변수를 설정하여 Sequel이 최대 1개의 연결만 사용하도록 강제합니다. -
연결 해제 확장:
DB.extension :temporarily_release_connection을 활성화하여 연결을 안전하게 공유할 수 있도록 합니다. -
트랜잭션 래핑: 모든 스크린샷 생성 로직을
DB.transaction(rollback: :always, auto_savepoint: true)블록으로 래핑합니다. 이 트랜잭션은 자동으로 롤백됩니다. -
연결 공유:
DB.temporarily_release_connection(conn)을 사용하여 트랜잭션에 할당된 연결을 일시적으로 연결 풀에 반환함으로써, 메인 스레드와 서버 스레드가 동일한 연결을 안전하게 공유할 수 있도록 합니다.
4. 스크린샷 생성 코드 구조 (RegenScreenshots 클래스)
-
스크린샷 목록 관리:
SCREENSHOT_DIR에 있는 모든 기존 스크린샷 파일 목록을SCREENSHOTS해시로 로드하여, 생성해야 할 스크린샷을 추적합니다. -
screenshot헬퍼 메서드: 주어진 이름으로 스크린샷을 찍고 (save_screenshot), 파일 시스템에 저장하며,SCREENSHOTS해시에서 해당 항목을 제거합니다. -
call메서드: Capybara DSL을 포함하며 (include Capybara::DSL),visit을 통해 페이지를 탐색하고screenshot메서드를 호출하여 필요한 시점에 스크린샷을 생성합니다. -
누락 스크린샷 경고: 프로그램 종료 시
RegenScreenshots::SCREENSHOTS에 남아있는 항목이 있다면, 누락된 스크린샷 목록을 경고로 출력하여 개발자가 이를 인지하고 업데이트하도록 합니다.