로컬 테스트 DB 노후화로 인해 Fabricators가 중복 이름 생성

방금 여러 테스트가 다음과 같은 오류로 실패했습니다:

 ActiveRecord::RecordInvalid:                                                                                                                      
       Validation failed: Name has already been taken           

그리고 문제의 원인이 아래인 것 같습니다:

  fab!(:the_group) { Fabricate(:group) }

이전까지는 이 코드들이 모두 정상적으로 작동했습니다. 제가 작업 중이던 다른 플러그인에서 비슷한 내용을 보고, 제 생각에는 무작위 이름을 직접 설정하는 방식으로 수정한 것 같습니다. 하지만 어제까지만 해도 이 코드들은 정상적으로 작동했던 것으로 기억합니다.

무언가 변경되었거나, 제가 실수로 어리석은 짓을 한 건가요?

수정(EDIT): Claude와 Discourse Helper Bot의 도움으로 위 fab을 아래 코드로 대체해 보았습니다.

  Fabricator(:the_group) do
    name { sequence(:group_name) { |i| "Test Group #{i}" } }
  end

하지만 어떻게 적용해야 하는지 정확히 파악하지 못했습니다.

그 후 위 !fab 대신 다음을 사용했습니다.

  let(:the_group) { Fabricate(:group) }

이로 인해 실패 건수가 12건에서 1건으로 줄었지만, 여전히 다음과 같은 오류로 실패하고 있습니다.

  1) Pfaffmanager::ServersController servers admin can get servers owned by a group                                                                    
     Failure/Error: let(:the_group) { Fabricate(:group) }                                                                                              
                                                                                                                                                       
     ActiveRecord::RecordInvalid:                                                                                                                      
       Validation failed: Name has already been taken   

어제 CDT 오전 10시 30분에 마지막 커밋을 했을 때부터 이 테스트 주변에 변경된 내용은 없다고 생각합니다.

이전 커밋으로 되돌렸더니 이번에는 다음과 같은 오류로 실패합니다.

                                                                                                                                                       
  1) Pfaffmanager::ServersController servers includes groups that the user is in                                                                       
     Failure/Error: let(:the_group) { Fabricate(:group) }                                                                                              
                                                                                                                                                       
     ActiveRecord::RecordInvalid:                                                                                                                      
       Validation failed: Name has already been taken                 

그리고 아무런 변경 없이 다시 실행해 보니 이번에는 다음 테스트에서 실패합니다.

  1) Pfaffmanager::ServersController servers can update group id if group owner                 
     Failure/Error: let(:the_group) { Fabricate(:group) }                                                                                              
                                                                                                                                                       
     ActiveRecord::RecordInvalid:                                                                                                                      
       Validation failed: Name has already been taken         

즉, 하나의 테스트에서 실패하고 있으며, 그 테스트는 랜덤으로 바뀌는 것 같습니다.

아마도 로컬 테스트 데이터베이스가 잘못된 상태로 변한 것일 수 있습니다. 다음을 실행해 보세요:

RAILS_ENV=test bin/rake db:drop db:create db:migrate

아니, 정말로 그레mlin들이었군요.

이상하게도 첫 번째 db:create는 멀티사이트 데이터베이스를 생성하지 않았는데, db:create rake 태스크만 단독으로 실행했을 때는 생성되었습니다. 그리고 마이그레이션이 성공했고, 그 뒤로는 그냥 잘 동작했습니다.

그리고 @Lilly, 님의 :eyes: 이 진짜 웃기네요.

아, 제가 테스트 데이터베이스를 오래 사용해 왔고, 무작위로 생성된 이름들이 이전 이름들과 충돌하기 시작했구나. 이제야 이해가 됩니다. 제 업그레이드 스크립트(git pull을 실행하고, all-the-plugins에서 코드를 새로고침하고, 루비 버전을 확인하는 등)를 수정해서 테스트 데이터베이스를 삭제(drop), 생성(create), 마이그레이션(migrate)하도록 변경했습니다.

하하. 음, 나는 네 코드 스니펫을 눈으로 확인해 봤는데, 이렇게 작동해야 한다고 꽤 확신했거든:

이론적으로 테스트 데이터베이스는 모든 테스트 실행 후 자동으로 정리되어야 합니다. 따라서 이런 상태가 되는 일은 절대 일어나서는 안 됩니다. 하지만… 테스트 프로세스가 어떤 방식으로든 비정상적으로 종료되면, 그 정리 작업(기술적으로 pg 세이브포인트의 복원)이 건너뛸 수 있다고 생각합니다.

따라서 이것은 일반적인 발생이 아니어야 합니다. 개인적으로는 이상한 실패가 시작되기 전까지는 drop/create/migrate를 수행하는 데 시간을 들이지 않을 것입니다.

하지만 대기 시간이 괜찮다면, 테스트 데이터베이스를 정기적으로 다시 만드는 데 아무런 해가 되지 않습니다 :+1:

그렇군요. 저는 ^c를 정말 좋아합니다.

대기하는 건 싫습니다. 주석 처리하고 나중에 기억하길 바랄 뿐이죠 :slight_smile:

이 문제를 해결해 주셔서 다시 한번 감사드립니다. 제정신이 아니라고 생각했거든요.