InfoGrab DocsInfoGrab Docs

QueryRecorder

테스트에서 N+1 쿼리 문제를 감지하고 방지하기 위한 QueryRecorder 도구의 사용법과 권장 패턴을 설명합니다.

QueryRecorder는 테스트에서 N+1 쿼리 문제 를 탐지하는 도구입니다. 9c623e3e 를 통해 spec/support/query_recorder.rb 에 구현되었습니다 원칙적으로 머지 리퀘스트는 쿼리 수를 늘리지 않아야 합니다 . N+1 쿼리를 피하기 위해 .includes(:author, :assignee) 와 같은 코드를 추가하고 있다면, QueryRecorder로 이를 테스트에서 강제하는 방안을 고려합니다. 이렇게 하지 않으면 모델을 추가로 조회하는 새 기능이 문제를 조용히 되살릴 수 있습니다. QueryRecorder의 동작 방식 # 이 방식의 테스트는 ActiveRecord가 실행한 SQL 쿼리 수를 세는 방식으로 동작합니다. 먼저 기준값을 측정하고, 데이터베이스에 새 레코드를 추가한 뒤 다시 측정합니다. 쿼리 수가 크게 늘어났다면 N+1 쿼리 문제가 있는 것입니다. 예를 들어 두 번의 측정 사이에 이슈 5개를 생성하면, N+1 문제가 있을 때 쿼리 수가 5만큼 늘어납니다. it "avoids N+1 database queries" , :request_store , :use_sql_query_cache do visit_some_page # warm-up control = ActiveRecord::QueryRecorder .new( skip_cached: false ) { visit_some_page } create_list( :issue , 5 ) expect { visit_some_page }.to issue_same_number_of_queries_as(control) end 기댓값과 기준값을 모두 QueryRecorder 인스턴스로 둘 수도 있습니다. it "avoids N+1 database queries" , :request_store , :use_sql_query_cache do visit_some_page # warm-up control = ActiveRecord::QueryRecorder .new( skip_cached: false ) { visit_some_page } create_list( :issue , 5 ) action = ActiveRecord::QueryRecorder .new( skip_cached: false ) { visit_some_page } expect(action).to issue_same_number_of_queries_as(control) end 경우에 따라서는 관계없는 이유로 실행마다 쿼리 수가 조금씩 달라질 수 있습니다. 이럴 때는 issue_same_number_of_queries_as(control).with_threshold(acceptable_change) 로 테스트해야 할 수도 있지만, 가능하면 피합니다. 이 테스트가 실패하고 기준값을 QueryRecorder 로 전달한 경우, 실패 메시지는 가장 긴 공통 접두사를 기준으로 쿼리를 대조하고 비슷한 쿼리를 묶어서 추가 쿼리가 어디에서 발생했는지 알려 줍니다. 권장 패턴 # N+1 쿼리 테스트의 권장 패턴에는 테스트가