初心者向けのE2Eテストの書き方ガイド

このチュートリアルでは、GitLab Community EditionGitLab Enterprise Edition のエンドツーエンド_(e2e_)テストの作成方法を説明します。

このチュートリアルを終えるまでに、以下のことができるようになります:

  • エンド・ツー・エンドのテストが必要かどうかの判断。
  • qa/ 内のディレクトリ構造を理解すること。
  • ログイン機能を検証する基本的なエンドツーエンドテストを書いてください。
  • 不足しているページ・オブジェクト・ライブラリを開発しましょう。

テストを書く前に

テストを書く前に、GitLab Development Kit(GDK)が仕様を実行するように設定されている必要があります。エンドツーエンドのテスト

  • qa/ ディレクトリ内部にコンテナがあります。
  • 独立で冪等でなければなりません。
  • リソース(プロジェクト、イシュー、ユーザーなど)をアドホックに作成。
  • UIとAPIのインターフェイスをテストし、APIを使用してUIテストを効率的に設定します。
note
詳細については、エンドツーエンドのテストのベストプラクティスを参照してください。

エンドツーエンド・テストが必要かどうかの判断

GitLabプロジェクトのエンドツーエンドテストを書く前に、特定の機能のコードカバレッジをチェックしましょう。ユニットレベル、機能レベル、インテグレーションレベルで十分なテストカバレッジが存在しますか?もし「はい」と答えたなら、エンドツーエンドテストは必要ありません

GitLab におけるレベルごとのテストのディストリビューションについては、Testing Levels を参照ください。

  • Testing levelsドキュメントのHow to test at the correct level?セクションを参照ください。
  • 機能の変更頻度をレビューしてください。あまり頻繁に変更されない安定した機能は、エンドツーエンドのテストでカバーする価値がないかもしれません。
  • 最後に、提案されたテストについて、その機能や下位レベルのテストの実装に携わっている開発者と議論しましょう。
caution
GitLab のカバレッジプロジェクトで、この機能について以前に書かれたテストがないか調べましょう。コードカバレッジを分析するには、どのアプリケーションファイルが特定の機能を実装しているかを理解しなければなりません。

このチュートリアルでは、ログインのエンドツーエンドテストを書きます。たとえ下位レベルのテストで十分カバーされていたとしても、ほとんどのエンドツーエンドフローの最初のステップであり、一番理解しやすいからです。

DevOpsステージの特定

GitLab QAのエンドツーエンドテストは、DevOpsライフサイクルのさまざまなステージごとに整理されています。ステージごとにテストを配置する場所を決定し、テストがどの機能に属するかを決定し、ステージの下のサブディレクトリに配置します。

DevOps lifecycle by stages

テストがEnterprise Editionのみの場合、テストはfeatures/ee ディレクトリに作成されますが、同じDevOpsライフサイクルフォーマットに従います。

スケルトンテストの作成

このチュートリアルの最初の部分では、Manage ステージが所有する login をテストします。qa/specs/features/browser_ui/1_manage/login 内部で、ファイルbasic_login_spec.rb を作成します。

内部context

RSpec.describe 外部ブロック参照

caution
RSpec4.0の仕様に準拠するため、13.2context の内部ブロックは廃止されました。代わりにRSpec.describe を使用してください。

内部RSpec.describe ブロック

Specs には、DevOps のステージを示す内部RSpec.describe があります。

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do

  end
end

describe

RSpec.describe の内部には、テストする機能を記述します。この場合、Login

# 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_and_authorization do

    end
  end
end

it ブロック (例)

どのテストスイートにも、少なくとも一つのit ブロック(例)が含まれています。エンドツーエンドのテストを書き始める良い方法は、テストケースの記述をit ブロックとして書くことです:

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

      end

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

      end
    end
  end
end

spec を実行した後、テストはログインして終了します。”What do we test?” という質問に答えてください。

# frozen_string_literal: true

module QA
  RSpec.describe 'Manage' do
    describe 'Login', product_group: :authentication_and_authorization 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_and_authorization 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) で、各例の前に実行され、各テストの最初にサインインするようにします。

リソースとページオブジェクトを使ったテストの設定

次に、ログイン以外のものをテストしてみましょう。計画ステージとプロジェクト管理グループが所有するイシューをテストしてみましょう。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のエンティティです。他の例としては

ページオブジェクト

Page Objectは 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: { qa_selector: 'closed_status_box' } }

specを実行します。

スペックを実行する前に、以下のことを確認してください:

  • 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”に記載されています。

エンドツーエンドのテストマージリクエストテンプレート

新しいエンドツーエンドテストを提出する場合、マージに成功する前に必要な追加手順については、「新しいエンドツーエンドテスト」マージリクエスト記述テンプレートを使用してください。