엔드 투 엔드 테스트 작성 초보자 가이드

이 튜토리얼은 GitLab Community EditionGitLab Enterprise Edition을 위한 엔드 투 엔드 (e2e) 테스트 작성을 안내합니다.

이 튜토리얼을 마치면 다음을 수행할 수 있습니다:

  • 엔드 투 엔드 테스트가 필요한지 확인합니다.
  • qa/ 내의 디렉터리 구조를 이해합니다.
  • 로그인 기능을 검증하는 기본 엔드 투 엔드 테스트를 작성합니다.
  • 부족한 페이지 오브젝트 라이브러리를 개발합니다.

테스트를 작성하기 전에

테스트를 작성하기 전에 GitLab Development Kit (GDK) 을 설정하여 스펙을 실행할 수 있어야 합니다. 엔드 투 엔드 테스트는 다음을 포함합니다:

  • qa/ 디렉터리 내에 포함됩니다.
  • 독립적이고 멱등해야 합니다.
  • 리소스 (프로젝트, 이슈, 사용자 등)를 ad-hoc 기반으로 생성해야 합니다.
  • UI 및 API 인터페이스를 테스트하고, API를 사용하여 UI 테스트를 효율적으로 설정해야 합니다.

참고: 더 많은 정보는 엔드 투 엔드 테스트 최상의 방법을 참조하십시오.

엔드 투 엔드 테스트가 필요한지 확인

특정 기능에 대한 코드 커버리지를 확인한 후 GitLab 프로젝트를 위해 엔드 투 엔드 테스트를 작성하기 전에 알맞은 테스트 커버리지가 단위, 기능 또는 통합 수준에서 충분히 있는지 확인합니다. 만약 라고 대답했다면, 엔드 투 엔드 테스트가 필요하지 않습니다.

GitLab 내에서 각 레벨에서의 테스트 분포에 대한 자세한 정보는 테스트 레벨을 참조하십시오.

  • 올바른 수준에서 테스트하는 방법? 섹션의 테스트 레벨 문서를 참조하십시오.
  • 기능이 얼마나 자주 변경되는지 확인합니다. 자주 변하지 않는 안정적인 기능은 이미 하위 레벨 테스트에서 다루고 있는 경우 엔드 투 엔드 테스트로 Cover할 가치가 없을 수 있습니다.
  • 마지막으로, 해당 기능을 구현하는 개발자 및 하위 레벨 테스트에 관련된 개발자와 해당 테스트를 논의하세요.

경고: 이 기능에 대한 이전에 작성된 테스트를 위해 GitLab 커버리지 프로젝트를 확인하세요. 코드 커버리지를 분석하려면 특정 기능을 구현하는 응용프로그램 파일을 이해해야 합니다.

이 튜토리얼에서는 이미 하위 레벨 테스트에서 충분히 다루어졌음에도 불구하고 로그인 엔드 투 엔드 테스트를 작성하고 있습니다. 그 이유는 대부분의 엔드 투 엔드 플로우에 필요한 첫 번째 단계이며 이해하기 쉽기 때문입니다.

DevOps 스테이지 식별

GitLab QA 엔드 투 엔드 테스트는 다양한 DevOps 라이프사이클의 스테이지로 구성됩니다. 해당 테스트를 스테이지에 따라 어디에 배치해야 하는지, 해당 테스트가 어떤 기능에 속하는지 확인한 후 해당 스테이지의 하위 디렉터리에 배치합니다.

스테이지 별 DevOps 라이프사이클

만약 해당 테스트가 Enterprise Edition 전용이라면 features/ee 디렉터리에 만들지만 동일한 DevOps 라이프사이클 포맷을 따릅니다.

스켈레톤 테스트 작성

이 튜토리얼의 첫 번째 부분에서는 로그인을 테스트하는데요, 해당 기능은 Manage 스테이지에서 소유하고 있습니다. qa/specs/features/browser_ui/1_manage/login 내부에 basic_login_spec.rb 파일을 만드세요.

외부 context 블록

외부 RSpec.describe 블록 참조

경고: 외부 context13.2에서 deprecated되었으며 RSpec 4.0 명세를 준수하기 위해 RSpec.describe를 사용해야 합니다.

외부 RSpec.describe 블록

스펙은 해당 DevOps 스테이지를 나타내는 외부 RSpec.describe를 포함합니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
  
  end
end

describe 블록

외부 RSpec.describe 내부에서 테스트할 기능을 설명합니다. 본 경우에는 로그인입니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login' do
    
    end
  end
end

product_group 메타데이터

product_group 메타데이터를 할당하고 해당 테스트가 어떤 제품 그룹에 속하는지 지정합니다. 본 경우에는 authentication_and_authorization입니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', product_group: :authentication do
    
    end
  end
end

it 블록 (예시)

모든 테스트 스위트에는 적어도 하나 이상의 it 블록(예시)이 포함되어야 합니다. 엔드 투 엔드 테스트를 작성하기 좋은 방법은 테스트 케이스 설명을 it 블록으로 작성하는 것입니다.

module QA
  RSpec.describe 'Manage' do
    describe 'Login', product_group: :authentication do
      it 'can login' do
      
      end
      
      it 'can logout' do
      
      end
    end
  end
end

테스트 작성

중요한 질문 중 하나는 “무엇을 테스트할 것인가?”이며 더 중요한 질문은 “어떻게 테스트할 것인가?”입니다.

먼저 로그인을 시작하세요.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', product_group: :authentication do
      it 'can login' do
        Flow::Login.sign_in
      
      end
      
      it 'can logout' do
        Flow::Login.sign_in
      
      end
    end
  end
end

스펙을 실행한 후, 테스트가 로그인하고 종료되어야 하며, 그 후에 “무엇을 테스트할 것인가?”라는 질문에 대답할 수 있어야 합니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', product_group: :authentication do
      it 'can login' do
        Flow::Login.sign_in
        
        Page::Main::Menu.perform do |menu|
          expect(menu).to be_signed_in
        end
      end
      
      it 'can logout' do
        Flow::Login.sign_in
        
        Page::Main::Menu.perform do |menu|
          menu.sign_out
          
          expect(menu).not_to be_signed_in
        end
      end
    end
  end
end

무엇을 테스트할까요?

  1. 로그인할 수 있는가?
  2. 로그아웃할 수 있는가?

어떻게 테스트할까요?

  1. 왼쪽 사이드바에 사용자 아바타가 나타나는지 확인합니다.
  2. 왼쪽 사이드바에 사용자 아바타가 나타나지 않는지 확인합니다.

배경에서 be_signed_in예측 매처로서 사용자 아바타를 확인하는 것을 구현합니다.

코드 중복 제거

테스트를 다시 작성하여 sign_in 호출을 중복하여 사용하는 것을 방지하기 위해 before 블록을 사용하세요.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', product_group: :authentication do
      before do
        Flow::Login.sign_in
      end
      
      it 'can login' do
        Page::Main::Menu.perform do |menu|
          expect(menu).to be_signed_in
        end
      end
      
      it 'can logout' do
        Page::Main::Menu.perform do |menu|
          menu.sign_out
          
          expect(menu).not_to be_signed_in
        end
      end
    end
  end
end

before 블록은 본질적으로 before(:each)로 각 예제 전에 실행되며, 이제 각 테스트의 시작 시점에 로그인을 보장합니다.

자원 및 페이지 객체를 사용한 테스트 설정

다음으로, 로그인 이외의 다른 것을 테스트해 보겠습니다. 우리는 이슈를 테스트합니다. 이슈는 Plan 단계와 프로젝트 관리 그룹에서 소유하고 있으므로 qa/specs/features/browser_ui/2_plan/issueissues_spec.rb라는 파일을 생성하세요.

# frozen_string_literal: true

module QA
  RSpec.describe 'Plan' do
    describe 'Issues', product_group: :project_management do
      let(:issue) { create(:issue) }
      
      before do
        Flow::Login.sign_in
        issue.visit!
      end
      
      it 'can close an issue' do
        Page::Project::Issue::Show.perform do |show|
          show.click_close_issue_button
          
          expect(show).to be_closed
        end
      end
    end
  end
end

다음과 같은 중요한 사항을 주의하세요:

  • 우리 예제 시작 지점에서 page/issue/show.rb 페이지에 있습니다.
  • 테스트는 필요한 것만 필요할 때 테스트하도록 구성됩니다.
  • 이슈는 API를 통해 속성화하여 시간을 절약합니다.
  • GitLab은 인스턴스 변수보다 let()을 선호합니다. 좋은 예를 참조하세요.
  • be_closed는 아직 page/project/issue/show.rb에 구현되지 않았지만, 다음 단계에서 구현됩니다.

이슈는 리소스로 속성화되며, 이는 UI 또는 API를 통해 생성할 수 있는 GitLab 엔터티입니다. 다른 예시로는 다음이 있습니다:

페이지 객체 작성

페이지 객체는 GitLab 내에서 페이지를 나타내는 스위트의 클래스입니다. 로그인 페이지가 이에 해당합니다. 이미 존재하는 이슈 보기 페이지 객체에 closed? 메서드를 추가하세요.

module Page::Project::Issue
  class Show
    view 'app/views/projects/issues/show.html.haml' do
      element 'closed-status-box'
    end
    
    def closed?
      has_element?('closed-status-box')
    end
  end
end

다음으로, 뷰 내에 closed-status-box 요소를 정의하여 페이지 객체에서 볼 수 있도록 만드세요.

-#=> app/views/projects/issues/show.html.haml
.issuable-status-box.status-box.status-box-issue-closed{ ..., data: { testid: 'closed-status-box' } }

테스트 실행

테스트를 실행하기 전에 다음 사항을 확인하세요:

  • GDK가 설치되어 있습니다.
  • GDK가 로컬에서 3000번 포트로 실행 중입니다.
  • 추가적인 RSpec 메타데이터 태그가 적용되지 않았습니다.
  • 작업 디렉터리가 GDK GitLab 설치 내 qa/입니다.
  • GitLab 인스턴스 수준 설정이 기본값입니다. 기본 설정을 변경했다면 일부 테스트가 예기치 않은 결과를 가져올 수 있습니다.
  • GDK는 처음 로그인시 비밀번호 변경을 요구하므로 root 사용자용 GDK 비밀번호를 포함해야 합니다.

테스트를 실행하려면 다음 명령을 실행하세요:

GITLAB_PASSWORD=<GDK root password> bundle exec rspec <test_file>

여기서 <test_file>은 다음과 같습니다:

  • 로그인 예제를 실행할 때 qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
  • 이슈 예제를 실행할 때 qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb

테스트 실행 및 가능한 옵션에 대한 자세한 정보는 “QA framework README”에서 설명되어 있습니다.

엔드 투 엔드 테스트 Merge Request 템플릿

새로운 엔드 투 엔드 테스트를 제출할 때, 성공적인 Merge 이전에 필요한 추가 단계에 대해 “New End to End Test” Merge Request 설명 템플릿을 사용하세요.