MySQL 통합 테스트는 실제 스키마를 만들고 데이터를 씁니다. 같은 데이터베이스와 계정을 다음 실행에 재사용하면 앞선 실행이 남긴 데이터가 새 결과에 영향을 줄 수 있습니다. 얼쑤에서는 실행마다 테스트 DB와 전용 계정을 만들고, 다른 DB에서 쓰는 접속 정보와 분리했습니다. 서버의 기동 조건이나 연결 한도를 시험할 때는 MySQL 인스턴스도 따로 띄웠습니다.

어디까지 분리할까

시험에서 바꾸는 것실행마다 분리할 대상
테이블, 테스트 데이터, 스키마 변경데이터베이스와 해당 DB에만 접근하는 전용 계정
기동 옵션, 최대 연결 수MySQL 인스턴스, 데이터 폴더, 접속 주소

Gradle의 통합 테스트에는 TEST_DB_URL, TEST_DB_USERNAME, TEST_DB_PASSWORD를 그 실행에만 전달했습니다. 새 계정은 시험에 필요한 권한을 받고, 데이터 쓰기 권한은 해당 DB에 한정했습니다. 실패한 실행도 정리할 수 있게 종료 절차를 테스트의 성공 여부와 분리했습니다.

연결 오류가 나면 먼저 서버가 떠 있는지 확인

macOS에서 폐기용 MySQL 8.4.9를 띄울 때, 데이터와 Unix 소켓(같은 컴퓨터에서 서버에 연결하는 데 쓰는 파일)을 깊은 임시 폴더에 함께 두었습니다. 클라이언트는 연결에 실패했습니다. 시작 로그에는 The socket file path is too long (> 103)이 남았고, 서버는 시작 직후 종료됐습니다. 당시 경로는 130자가 넘었습니다. 로그에 나온 103은 이 환경에서 소켓 주소에 쓸 수 있는 바이트 수입니다. 한 글자가 여러 바이트를 쓰는 경로에서는 글자 수와 바이트 수가 다릅니다.

데이터 폴더는 그대로 두고 서버의 --socket에 짧은 경로를 지정하니 같은 MySQL이 기동했습니다. 클라이언트도 새 소켓 주소로 연결했습니다. 같은 컴퓨터에서 시험을 여러 개 실행할 때는 짧으면서 실행마다 다른 소켓 이름을 써야 접속 대상이 겹치지 않습니다.

서버가 정상 기동했는데 연결 요청이 많아져 새 연결을 거부하는 경우에는 확인할 지점이 달라집니다. Spring 테스트 53개 실패와 MySQL 연결 한도에서 그 사례를 다룹니다.

데이터 폴더는 종료와 파일 해제를 확인한 뒤 정리

폐기용 인스턴스는 실행할 때 지정한 데이터 폴더를 기준으로 프로세스를 찾습니다. 해당 인스턴스에 종료를 요청하고, 프로세스가 멈췄는지와 열린 파일이 남았는지 차례대로 확인합니다. 종료를 확인하지 못하거나 폴더 경로가 예상과 다르면 데이터를 남겨 원인을 조사할 수 있게 합니다. 이 절차는 폐기용 인스턴스에 적용합니다.

실행과 정리를 묶어 두면 테스트가 실패하더라도 다음 실행이 같은 데이터나 소켓에 붙는 일을 줄일 수 있습니다. 연결 실패를 살필 때도 먼저 서버 시작 로그를 확인하고, 그다음 실제로 연결을 시도한 주소와 서버가 사용한 주소를 대조할 수 있습니다.