기능 플래그를 사용한 테스트

기능 플래그를 사용하여 특정 테스트를 실행하려면 QA::Runtime::Feature 클래스를 사용하여 기능 플래그를 활성화 및 비활성화할 수 있습니다 (API를 통해).

기능 플래그를 변경하려면 관리자 권한이 필요합니다. QA::Runtime::Feature는 적절한 엑세스 토큰을 제공하면(권장) 또는 GITLAB_ADMIN_USERNAMEGITLAB_ADMIN_PASSWORD를 제공하면 관리자로 자동 인증됩니다.

feature_flag RSpec 태그

테스트가 적절한 환경에서 건너뛸 수 있도록 feature_flag 태그를 포함해야 합니다.

선택적 메타데이터:

name

  • 형식: feature_flag: { name: 'feature_flag_name' }
  • 현재는 정보 목적으로만 사용됩니다. 빠르게 테스트 중인 기능 플래그를 식별하는 데 도움이 되도록 포함되어야 합니다.

scope

  • 형식: feature_flag: { name: 'feature_flag_name', scope: :project }
  • scope:global로 설정되면 테스트는 모든 라이브 .com 환경에서 건너뜁니다. 이는 기능 플래그 변경이 다른 테스트나 사용자에 영향을 미치는 문제를 피하기 위한 것입니다.
  • 다른 값(예: :project, :group 또는 :user)으로 scope가 설정되거나 scope가 지정되지 않은 경우, 또는 다른 값(예: :project, :group, 또는 :user)으로 scope가 지정되지 않은 경우 테스트는 canary, production, 그리고 pre-production에서만 건너뜁니다. 이는 관리자 액세스가 해당 환경에서 사용할 수 없기 때문입니다.

경고: 먼저 기능 플래그를 그룹, 프로젝트, 사용자에 대해서만 사용해 보는 것이 좋습니다.

  • 전역 기능 플래그를 사용해야 하는 경우, feature_flag 메타데이터에 scope: :global를 적용하는 것이 강력히 권장됩니다. 그러나 이는 SET의 재량에 따라 리스크 수준을 결정하는 데 달려 있습니다.
    • 예를 들어, 특정 시나리오에서 테스트가 전체 애플리케이션의 작은 영역에만 영향을 미치고 라이브 환경에서 중요한 문제를 확인하기 위해 필요한 전역 기능 플래그를 사용하는 경우 테스트를 건너뛰는 것이 더 위험할 수 있습니다. 이러한 경우에는 scope를 메타데이터에서 제외하여 라이브 환경에서 테스트를 계속 실행할 수 있도록하여야 합니다.

requires_admin에 대한 참고 사항: 테스트 내에서 기능 플래그를 업데이트하는 것과 관련이 없는 다른 작업에 관리자 액세스가 필요한 경우에도 여전히 이 태그를 적용해야 합니다(예: API를 통해 사용자를 만드는 것 등).

아래 코드는 테스트에서 생성된 프로젝트에 대해 :feature_flag_name이라는 기능 플래그를 활성화합니다:

RSpec.describe "with feature flag enabled", feature_flag: {
  name: 'feature_flag_name',
  scope: :project
  } do

  let(:project) { Resource::Project.fabricate_via_api! }

  around do |example|
    Runtime::Feature.enable(:feature_flag_name, project: project)
    example.run
    Runtime::Feature.disable(:feature_flag_name, project: project)
  end

  it "feature flag test" do
    # 기능 플래그를 활성화하고 테스트를 실행합니다.
    # 이는 테스트에서 생성된 프로젝트에만 영향을 미칩니다.
  end
end

enabledisable 메서드는 먼저 플래그를 설정한 다음 API에서 업데이트된 값을 확인합니다.

비슷하게, 그룹, 사용자, 또는 기능 그룹에 대한 기능을 활성화할 수 있습니다:

group = Resource::Group.fabricate_via_api!
Runtime::Feature.enable(:feature_flag_name, group: group)

user = Resource::User.fabricate_via_api!
Runtime::Feature.enable(:feature_flag_name, user: user)

feature_group = "a_feature_group"
Runtime::Feature.enable(:feature_flag_name, feature_group: feature_group)

scope가 제공되지 않으면 기능 플래그는 인스턴스 전체에 설정됩니다:

# 모든 사용자에게 영향을 미칩니다!
Runtime::Feature.enable(:feature_flag_name)

선택기(selector) 사용

새로운 기능은 대부분 vue 컴포넌트나 haml 파일을 새로운 것으로 교체합니다 대부분의 경우 새 파일 또는 컴포넌트는 기능 플래그만 활성화된 상태에서만 접근할 수 있습니다. 이 접근 방식은 테스트가 기능 플래그를 켜고 끈 상태에서 모두 통과해야 하는 경우에 문제가 됩니다:

  1. 새 컴포넌트 또는 파일 내에 또 다른 선택기를 만듭니다.
  2. 이전 선택기와 동일한 이름을 부여합니다.

선택기는 페이지 객체의 특정 프론트엔드 파일에 연결되어 있으며, qa:selectors 테스트 내에서 사용 가능한지 확인합니다. 언급된 선택기가 해당 프론트엔드 파일 내에 없을 경우 테스트가 실패합니다. 새로운 선택기를 페이지 객체에 추가하여 선택기가 기능 플래그가 활성화되거나 비활성화될 때도 사용 가능하도록 하고 이전 선택기는 그대로 둡니다. 테스트는 올바른 선택기를 사용하고 없는 선택기를 여전히 감지합니다.

새로운 기능이 이미 있는 프론트엔드 파일을 변경한다면, 같은 이름으로 새 선택기를 추가할 수 있습니다. 그러나 페이지에는 하나의 선택기만 표시됩니다.

  1. 다른 선택기를 기능 플래그로 비활성화합니다.
  2. 기능 플래그가 제거되면 프론트엔드 파일에서 이전 선택기를 삭제하고 페이지 객체 파일에서도 삭제하도록 주석을 추가합니다.

예시 이전

# This is the link to the old file
view 'app/views/devise/passwords/edit.html.haml' do
  # The new selector should have the same name
  element :password_field
  ...
end

예시 후

view 'app/views/devise/passwords/edit.html.haml' do
  element :password_field
  ...
end

# 이제 셀렉터를 확인할 수 있습니다
view 'app/views/devise/passwords/new_edit_behind_ff.html.haml' do
  # 셀렉터는 같은 이름을 가지고 있습니다
  element :password_field
end

리소스 클래스 사용하기

리소스 클래스가 기능 플래그가 활성화될 때 다르게 작동해야 한다면, 클래스 내부에 기능 플래그의 이름을 가진 변수를 토글하십시오. 이 변수와 조건은 모든 액션이 적절하게 처리되도록 보장합니다.

이 변수를 fabricate_via_api 호출 내부에서 설정할 수 있습니다. 일관성 있는 접근 방식으로:

  • 비활성화된 것이 아니라 활성화된 것을 체크하세요.
  • 변수 명 끝에 activated를 추가하세요.
  • initialize 메서드 내부에서 변수의 기본값을 설정하세요.

예를 들어:

def initialize
  name_of_the_feature_flag_activated = false
  ...
end

정리

기능 플래그가 제거된 후, 리소스 클래스를 정리하고 변수를 삭제하십시오. 모든 메서드는 이제 기본 상태의 조건 절차를 사용해야 합니다.

캐싱으로 인한 flakiness 관리

GitLab 내의 모든 응용프로그램 설정과 모든 기능 플래그는 1분 동안 캐시됩니다. 모든 캐싱은 테스트 중에는 비활성화되며, 정적 환경에서만 활성화됩니다.

테스트가 기능 플래그를 변경하면, 활성화된 기능 플래그로만 표시되는 요소들로 인해 불안정한 동작을 일으킬 수 있습니다. 이러한 동작을 피하기 위해 기능 플래그 뒤의 요소에 대해 대기를 추가하세요.

기능 플래그가 활성화된 시나리오 실행

기능 플래그가 활성화된 전체 시나리오를 수정하거나 새로 작성할 필요 없이 실행하는 것도 가능합니다.

기능 플래그가 활성화된 상태로 시나리오 전체를 실행할 수 있습니다. 자세한 내용은 QA README를 참조하세요.

기능 플래그가 활성화된 상태에서 엔드 투 엔드 테스트가 통과되는지 확인

기능 플래그가 Staging이나 GitLab.com에서 활성화되기 전에 엔드 투 엔드 테스트가 통과되어야 합니다. 업데이트가 필요한 테스트는 quad-planning의 일환으로 식별해야 합니다. 관련 담당 소프트웨어 엔지니어 테스트는 테스트를 업데이트하거나 다른 엔지니어가 그 일을 돕도록 지원할 책임이 있습니다. 그러나 변경 내용이 quad-planning을 거치지 않은 경우 필수적인 테스트 업데이트가 이루어지지 않으면 배포가 차단될 수 있습니다.

기능 플래그 정의 변경 시 자동 테스트 실행

엔드 투 엔드 테스트가 통과되었는지 확인하는 두 가지 방법이 있습니다:

  • 만약 병합 요청이 기능 플래그 정의 파일을 추가하거나 수정하는 경우, 두 개의 e2e:package-and-test 작업 (ee:instance-parallelee:instance-parallel-ff-inverse)이 자동으로 병합 요청 파이프라인에 포함됩니다. 하나의 작업은 기본 기능 플래그 상태로 응용프로그램을 실행하고, 다른 하나는 그것을 반대 값으로 설정합니다. 이 두 작업은 동일한 테스트 스위트를 실행하여 기능 플래그를 활성화하거나 비활성화 상태로 테스트가 통과되는지 확인합니다.
  • 경우에 따라 엔드 투 엔드 테스트 작업이 자동으로 트리거되지 않았거나 기본 기능 플래그 값을 사용하여 테스트를 실행한 경우 (이는 원하는 바가 아닐 수 있음), 피처 플래그를 활성화하는 드래프트 MR을 만들 수 있습니다. 이를 통해 기능 플래그를 활성화하고 비활성화한 상태에서 모든 E2E 테스트가 통과되는지 확인할 수 있습니다.

활성화된 기능 플래그로 인한 엔드 투 엔드 테스트 실패 문제 해결

기능 플래그를 활성화하면 엔드 투 엔드 테스트가 실패할 수도 있습니다. 이때 실패한 파이프라인의 아티팩트를 확인하여 실패한 테스트의 스크린샷을 볼 수 있습니다. 그리고 나서:

  • 업데이트가 필요한 테스트를 찾아내고, 해당하는 담당 소프트웨어 엔지니어 테스트에게 연락하여 테스트를 업데이트하거나 다른 엔지니어가 그 일을 돕도록 지원할 책임이 있습니다. 그러나 변경 내용이 quad-planning을 거치지 않은 경우 필수적인 테스트 업데이트가 이루어지지 않으면 배포가 차단될 수 있습니다.
  • 실패한 테스트를 로컬에서 기능 플래그를 활성화하여 실행할 수 있습니다. 이 옵션은 상당한 설정이 필요하지만, 브라우저가 실패한 테스트를 실행하는 동안 브라우저의 동작을 볼 수 있어 문제를 빠르게 디버깅하는 데 도움이 됩니다. 또한, 일반적인 블로커에 대한 지원은 E2E 테스트를 위한 문제 해결 가이드를 참조할 수 있습니다.

기능 개발 중의 테스트 실행

만약 엔드 투 엔드 테스트가 피쳐 플래그를 활성화한다면, 해당 엔드 투 엔드 테스트 스위트는 병합 요청 파이프라인에서 e2e:package-and-test 작업을 실행하여 변경 사항을 테스트하는 데 사용될 수 있습니다. 피쳐 플래그와 관련 변경 사항이 이미 병합되었다면, 해당 테스트가 기본 브랜치에서 통과하는지 확인할 수 있습니다. 엔드 투 엔드 테스트는 매 2시간마다 기본 브랜치에서 실행되며 결과는 테스트 세션 보고서에 게시됩니다. 해당 보고서는 testcase-sessions 프로젝트에서 확인할 수 있습니다.

만약 관련 테스트가 피쳐 플래그를 직접 활성화하지 않는다면, 해당 테스트가 업데이트가 필요한지 확인할 수 있습니다. 이를 위해 피쳐 플래그 정의 파일을 통해 플래그를 기본적으로 활성화하는 임시 병합 요청을 엽니다. 이렇게 하면 엔드 투 엔드 테스트 스위트가 자동으로 실행됩니다. 테스트가 통과하면 해당 병합 요청을 닫을 수 있습니다. 테스트를 업데이트해야 하는 경우, 관련 품질 부서의 안정적인 대응자나 해당 그룹에 안정적인 대응자가 없다면, 테스트를 업데이트하는 데 도움이 필요하다면 테스트를 담당하는 소프트웨어 엔지니어에게 문의하십시오.