InfoGrab DocsInfoGrab Docs

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

요약

이 튜토리얼은 GitLab 커뮤니티 에디션(Community Edition) 및 GitLab 엔터프라이즈 에디션(Enterprise Edition)을 위한 엔드-투-엔드(e2e) 테스트 작성 과정을 안내합니다. 이 튜토리얼을 완료하면 다음을 수행할 수 있습니다:

이 튜토리얼은 GitLab 커뮤니티 에디션(Community Edition)GitLab 엔터프라이즈 에디션(Enterprise Edition)을 위한 엔드-투-엔드(e2e) 테스트 작성 과정을 안내합니다.

이 튜토리얼을 완료하면 다음을 수행할 수 있습니다:

  • 엔드-투-엔드 테스트가 필요한지 판단합니다.

  • qa/ 내의 디렉터리 구조를 이해합니다.

  • 로그인 기능을 검증하는 기본 엔드-투-엔드 테스트를 작성합니다.

  • 누락된 페이지 오브젝트(page object) 라이브러리를 개발합니다.

테스트를 작성하기 전에#

테스트를 작성하기 전에, spec을 실행하도록 GitLab Development Kit(GDK)이 구성되어 있어야 합니다. 엔드-투-엔드 테스트는:

  • qa/ 디렉터리 내에 포함됩니다.

  • 독립적이고 멱등성(idempotent)을 가져야 합니다.

  • 필요에 따라 즉석으로 리소스(예: 프로젝트, 이슈, 사용자)를 생성합니다.

  • UI 및 API 인터페이스를 테스트하며, API를 활용하여 UI 테스트를 효율적으로 설정합니다.

엔드-투-엔드 테스트 필요 여부 판단#

GitLab 프로젝트의 엔드-투-엔드 테스트를 작성하기 전에, 특정 기능의 코드 커버리지를 확인하세요. 유닛, 기능, 또는 통합 레벨에서 충분한 테스트 커버리지가 이미 존재하나요? 라고 답한다면 엔드-투-엔드 테스트는 필요하지 않습니다.

GitLab에서 레벨별 테스트 분포에 대한 정보는 Testing Levels를 참조하세요.

  • Testing levels 문서의 How to test at the correct level? 섹션을 확인하세요.

  • 기능이 얼마나 자주 변경되는지 검토하세요. 하위 레벨 테스트에서 이미 커버된 안정적인 기능은 엔드-투-엔드 테스트로 커버할 필요가 없을 수 있습니다.

  • 마지막으로, 기능 구현 및 하위 레벨 테스트에 참여한 개발자들과 제안된 테스트에 대해 논의하세요.

이 기능에 대해 이전에 작성된 테스트를 GitLab 커버리지 프로젝트에서 확인하세요. 코드 커버리지를 분석하려면 특정 기능을 구현하는 애플리케이션 파일을 이해해야 합니다.

이 튜토리얼에서는 하위 레벨 테스트에서 이미 충분히 커버됐지만, 대부분의 엔드-투-엔드 플로우의 첫 단계이자 가장 이해하기 쉬운 로그인 엔드-투-엔드 테스트를 작성합니다.

DevOps 단계 식별#

GitLab QA 엔드-투-엔드 테스트는 DevOps 라이프사이클의 다양한 단계별로 구성됩니다. 단계(stage)에 따라 테스트가 위치할 곳을 결정하고, 테스트가 속하는 기능을 파악한 다음, 해당 단계 아래 하위 디렉터리에 배치하세요.

[

](/19.1/development/testing_guide/end_to_end/beginners_guide/img/gl-devops-lifecycle-by-stage_v12_10.png)

테스트가 엔터프라이즈 에디션 전용인 경우, features/ee 디렉터리에 테스트를 생성하되 동일한 DevOps 라이프사이클 형식을 따릅니다.

기본 테스트 골격 생성#

이 튜토리얼의 첫 번째 부분에서는 Manage 단계가 소유한 로그인을 테스트합니다. qa/specs/features/browser_ui/1_manage/login 디렉터리 내에 basic_login_spec.rb 파일을 생성하세요.

외부 context 블록#

RSpec.describe 외부 블록을 참조하세요.

외부 context는 RSpec 4.0 사양을 준수하기 위해 13.2에서 deprecated됩니다. 대신 RSpec.describe를 사용하세요.

외부 RSpec.describe 블록#

Spec에는 DevOps 단계를 나타내는 외부 RSpec.describe가 있습니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do

  end
end

describe 블록#

외부 RSpec.describe 안에 테스트할 기능을 describe합니다. 이 경우 Login입니다.

# frozen_string_literal: true

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

    end
  end
end

feature_category 메타데이터#

feature_category 메타데이터를 할당하고 이 테스트가 속하는 기능 카테고리를 지정합니다. 이 경우 system_access입니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', feature_category: :system_access do

    end
  end
end

it 블록(예시)#

모든 테스트 스위트에는 최소 하나의 it 블록(예시)이 포함됩니다. 엔드-투-엔드 테스트 작성을 시작하는 좋은 방법은 테스트 케이스 설명을 it 블록으로 작성하는 것입니다:

module QA
  RSpec.describe 'Manage' do
    describe 'Login', feature_category: :system_access 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', feature_category: :system_access do
      it 'can login' do
        Flow::Login.sign_in

      end

      it 'can logout' do
        Flow::Login.sign_in

      end
    end
  end
end

Flows에 대한 자세한 내용은 Flows를 참조하세요.

spec을 실행한 후, 테스트는 로그인하고 종료되어야 합니다. 그런 다음 "무엇을 테스트하는가?"라는 질문에 답해야 합니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', feature_category: :system_access 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

무엇을 테스트하는가?

  • 로그인할 수 있는가?

  • 로그아웃할 수 있는가?

어떻게 테스트하는가?

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

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

내부적으로 be_signed_in사용자 아바타 확인을 구현하는 predicate matcher입니다.

코드 중복 제거#

sign_in 호출이 중복되므로 테스트 설정에 before 블록을 사용하도록 테스트를 리팩토링합니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', feature_category: :system_access 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 단계와 Project Management 그룹이 소유한 이슈를 테스트해봅시다. qa/specs/features/browser_ui/2_plan/issueissues_spec.rb라는 파일을 생성합니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Plan' do
    describe 'Issues', feature_category: :team_planning 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()을 선호합니다. best practices를 참조하세요.

  • be_closed는 아직 page/project/issue/show.rb에 구현되어 있지 않지만, 다음 단계에서 구현됩니다.

이슈는 Resource로 생성됩니다. Resource는 UI 또는 API를 통해 생성할 수 있는 GitLab 엔티티입니다. 다른 예시는 다음과 같습니다:

페이지 오브젝트 작성#

페이지 오브젝트(Page Object)는 GitLab 내의 페이지를 나타내는 스위트 내의 클래스입니다. Login 페이지가 한 예시입니다. Issue Show 페이지의 페이지 오브젝트가 이미 존재하므로, 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' } }

Spec 실행#

Spec을 실행하기 전에 다음을 확인하세요:

  • GDK가 설치되어 있습니다.

  • GDK가 포트 3000에서 로컬로 실행 중입니다.

  • 추가적인 RSpec 메타데이터 태그가 적용되지 않았습니다.

  • 작업 디렉터리가 GDK GitLab 설치 내의 qa/입니다.

  • GitLab 인스턴스 수준 설정이 기본값입니다. 기본 설정을 변경한 경우 일부 테스트에서 예상치 못한 결과가 발생할 수 있습니다.

  • GDK는 첫 로그인 시 비밀번호 변경이 필요하므로, root 사용자의 GDK 비밀번호를 포함해야 합니다.

Spec을 실행하려면 다음 명령어를 실행하세요:

GITLAB_PASSWORD= bundle exec rspec <test_file>

<test_file>은 다음과 같습니다:

  • Login 예시를 실행할 때는 qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb.

  • Issue 예시를 실행할 때는 qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb.

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

코드 리뷰를 위한 테스트 준비#

코드 리뷰를 위해 테스트를 제출하기 전에, 다음과 같은 몇 가지 정리 작업을 수행해야 합니다:

자세한 내용은 엔드-투-엔드 테스트 모범 사례엔드-투-엔드 테스트 스타일 가이드를 참조하세요.

엔드-투-엔드 테스트 머지 리퀘스트 템플릿#

새로운 엔드-투-엔드 테스트를 제출할 때, 성공적인 머지 전에 필요한 추가 단계를 위해 "New End to End Test" 머지 리퀘스트 설명 템플릿을 사용하세요.

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

GitLab v19.1
원문 보기
요약

이 튜토리얼은 GitLab 커뮤니티 에디션(Community Edition) 및 GitLab 엔터프라이즈 에디션(Enterprise Edition)을 위한 엔드-투-엔드(e2e) 테스트 작성 과정을 안내합니다. 이 튜토리얼을 완료하면 다음을 수행할 수 있습니다:

이 튜토리얼은 GitLab 커뮤니티 에디션(Community Edition)GitLab 엔터프라이즈 에디션(Enterprise Edition)을 위한 엔드-투-엔드(e2e) 테스트 작성 과정을 안내합니다.

이 튜토리얼을 완료하면 다음을 수행할 수 있습니다:

  • 엔드-투-엔드 테스트가 필요한지 판단합니다.

  • qa/ 내의 디렉터리 구조를 이해합니다.

  • 로그인 기능을 검증하는 기본 엔드-투-엔드 테스트를 작성합니다.

  • 누락된 페이지 오브젝트(page object) 라이브러리를 개발합니다.

테스트를 작성하기 전에#

테스트를 작성하기 전에, spec을 실행하도록 GitLab Development Kit(GDK)이 구성되어 있어야 합니다. 엔드-투-엔드 테스트는:

  • qa/ 디렉터리 내에 포함됩니다.

  • 독립적이고 멱등성(idempotent)을 가져야 합니다.

  • 필요에 따라 즉석으로 리소스(예: 프로젝트, 이슈, 사용자)를 생성합니다.

  • UI 및 API 인터페이스를 테스트하며, API를 활용하여 UI 테스트를 효율적으로 설정합니다.

엔드-투-엔드 테스트 필요 여부 판단#

GitLab 프로젝트의 엔드-투-엔드 테스트를 작성하기 전에, 특정 기능의 코드 커버리지를 확인하세요. 유닛, 기능, 또는 통합 레벨에서 충분한 테스트 커버리지가 이미 존재하나요? 라고 답한다면 엔드-투-엔드 테스트는 필요하지 않습니다.

GitLab에서 레벨별 테스트 분포에 대한 정보는 Testing Levels를 참조하세요.

  • Testing levels 문서의 How to test at the correct level? 섹션을 확인하세요.

  • 기능이 얼마나 자주 변경되는지 검토하세요. 하위 레벨 테스트에서 이미 커버된 안정적인 기능은 엔드-투-엔드 테스트로 커버할 필요가 없을 수 있습니다.

  • 마지막으로, 기능 구현 및 하위 레벨 테스트에 참여한 개발자들과 제안된 테스트에 대해 논의하세요.

이 기능에 대해 이전에 작성된 테스트를 GitLab 커버리지 프로젝트에서 확인하세요. 코드 커버리지를 분석하려면 특정 기능을 구현하는 애플리케이션 파일을 이해해야 합니다.

이 튜토리얼에서는 하위 레벨 테스트에서 이미 충분히 커버됐지만, 대부분의 엔드-투-엔드 플로우의 첫 단계이자 가장 이해하기 쉬운 로그인 엔드-투-엔드 테스트를 작성합니다.

DevOps 단계 식별#

GitLab QA 엔드-투-엔드 테스트는 DevOps 라이프사이클의 다양한 단계별로 구성됩니다. 단계(stage)에 따라 테스트가 위치할 곳을 결정하고, 테스트가 속하는 기능을 파악한 다음, 해당 단계 아래 하위 디렉터리에 배치하세요.

[

](/19.1/development/testing_guide/end_to_end/beginners_guide/img/gl-devops-lifecycle-by-stage_v12_10.png)

테스트가 엔터프라이즈 에디션 전용인 경우, features/ee 디렉터리에 테스트를 생성하되 동일한 DevOps 라이프사이클 형식을 따릅니다.

기본 테스트 골격 생성#

이 튜토리얼의 첫 번째 부분에서는 Manage 단계가 소유한 로그인을 테스트합니다. qa/specs/features/browser_ui/1_manage/login 디렉터리 내에 basic_login_spec.rb 파일을 생성하세요.

외부 context 블록#

RSpec.describe 외부 블록을 참조하세요.

외부 context는 RSpec 4.0 사양을 준수하기 위해 13.2에서 deprecated됩니다. 대신 RSpec.describe를 사용하세요.

외부 RSpec.describe 블록#

Spec에는 DevOps 단계를 나타내는 외부 RSpec.describe가 있습니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do

  end
end

describe 블록#

외부 RSpec.describe 안에 테스트할 기능을 describe합니다. 이 경우 Login입니다.

# frozen_string_literal: true

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

    end
  end
end

feature_category 메타데이터#

feature_category 메타데이터를 할당하고 이 테스트가 속하는 기능 카테고리를 지정합니다. 이 경우 system_access입니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', feature_category: :system_access do

    end
  end
end

it 블록(예시)#

모든 테스트 스위트에는 최소 하나의 it 블록(예시)이 포함됩니다. 엔드-투-엔드 테스트 작성을 시작하는 좋은 방법은 테스트 케이스 설명을 it 블록으로 작성하는 것입니다:

module QA
  RSpec.describe 'Manage' do
    describe 'Login', feature_category: :system_access 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', feature_category: :system_access do
      it 'can login' do
        Flow::Login.sign_in

      end

      it 'can logout' do
        Flow::Login.sign_in

      end
    end
  end
end

Flows에 대한 자세한 내용은 Flows를 참조하세요.

spec을 실행한 후, 테스트는 로그인하고 종료되어야 합니다. 그런 다음 "무엇을 테스트하는가?"라는 질문에 답해야 합니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', feature_category: :system_access 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

무엇을 테스트하는가?

  • 로그인할 수 있는가?

  • 로그아웃할 수 있는가?

어떻게 테스트하는가?

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

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

내부적으로 be_signed_in사용자 아바타 확인을 구현하는 predicate matcher입니다.

코드 중복 제거#

sign_in 호출이 중복되므로 테스트 설정에 before 블록을 사용하도록 테스트를 리팩토링합니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', feature_category: :system_access 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 단계와 Project Management 그룹이 소유한 이슈를 테스트해봅시다. qa/specs/features/browser_ui/2_plan/issueissues_spec.rb라는 파일을 생성합니다.

# frozen_string_literal: true

module QA
  RSpec.describe 'Plan' do
    describe 'Issues', feature_category: :team_planning 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()을 선호합니다. best practices를 참조하세요.

  • be_closed는 아직 page/project/issue/show.rb에 구현되어 있지 않지만, 다음 단계에서 구현됩니다.

이슈는 Resource로 생성됩니다. Resource는 UI 또는 API를 통해 생성할 수 있는 GitLab 엔티티입니다. 다른 예시는 다음과 같습니다:

페이지 오브젝트 작성#

페이지 오브젝트(Page Object)는 GitLab 내의 페이지를 나타내는 스위트 내의 클래스입니다. Login 페이지가 한 예시입니다. Issue Show 페이지의 페이지 오브젝트가 이미 존재하므로, 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' } }

Spec 실행#

Spec을 실행하기 전에 다음을 확인하세요:

  • GDK가 설치되어 있습니다.

  • GDK가 포트 3000에서 로컬로 실행 중입니다.

  • 추가적인 RSpec 메타데이터 태그가 적용되지 않았습니다.

  • 작업 디렉터리가 GDK GitLab 설치 내의 qa/입니다.

  • GitLab 인스턴스 수준 설정이 기본값입니다. 기본 설정을 변경한 경우 일부 테스트에서 예상치 못한 결과가 발생할 수 있습니다.

  • GDK는 첫 로그인 시 비밀번호 변경이 필요하므로, root 사용자의 GDK 비밀번호를 포함해야 합니다.

Spec을 실행하려면 다음 명령어를 실행하세요:

GITLAB_PASSWORD= bundle exec rspec <test_file>

<test_file>은 다음과 같습니다:

  • Login 예시를 실행할 때는 qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb.

  • Issue 예시를 실행할 때는 qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb.

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

코드 리뷰를 위한 테스트 준비#

코드 리뷰를 위해 테스트를 제출하기 전에, 다음과 같은 몇 가지 정리 작업을 수행해야 합니다:

자세한 내용은 엔드-투-엔드 테스트 모범 사례엔드-투-엔드 테스트 스타일 가이드를 참조하세요.

엔드-투-엔드 테스트 머지 리퀘스트 템플릿#

새로운 엔드-투-엔드 테스트를 제출할 때, 성공적인 머지 전에 필요한 추가 단계를 위해 "New End to End Test" 머지 리퀘스트 설명 템플릿을 사용하세요.