- テストを書く前に
- エンドツーエンド・テストが必要かどうかの判断
- DevOpsステージの特定
- スケルトンテストの作成
- テストを書きます
- コードの複製を削除
- リソースとページオブジェクトを使ったテストの設定
- ページオブジェクト
- specを実行します。
- エンドツーエンドのテストマージリクエストテンプレート
初心者向けのE2Eテストの書き方ガイド
このチュートリアルでは、GitLab Community EditionとGitLab Enterprise Edition のエンドツーエンド_(e2e_)テストの作成方法を説明します。
このチュートリアルを終えるまでに、以下のことができるようになります:
- エンド・ツー・エンドのテストが必要かどうかの判断。
-
qa/
内のディレクトリ構造を理解すること。 - ログイン機能を検証する基本的なエンドツーエンドテストを書いてください。
- 不足しているページ・オブジェクト・ライブラリを開発しましょう。
テストを書く前に
テストを書く前に、GitLab Development Kit(GDK)が仕様を実行するように設定されている必要があります。エンドツーエンドのテスト
-
qa/
ディレクトリ内部にコンテナがあります。 - 独立で冪等でなければなりません。
- リソース(プロジェクト、イシュー、ユーザーなど)をアドホックに作成。
- UIとAPIのインターフェイスをテストし、APIを使用してUIテストを効率的に設定します。
エンドツーエンド・テストが必要かどうかの判断
GitLabプロジェクトのエンドツーエンドテストを書く前に、特定の機能のコードカバレッジをチェックしましょう。ユニットレベル、機能レベル、インテグレーションレベルで十分なテストカバレッジが存在しますか?もし「はい」と答えたなら、エンドツーエンドテストは必要ありません。
GitLab におけるレベルごとのテストのディストリビューションについては、Testing Levels を参照ください。
- Testing levelsドキュメントのHow to test at the correct level?セクションを参照ください。
- 機能の変更頻度をレビューしてください。あまり頻繁に変更されない安定した機能は、エンドツーエンドのテストでカバーする価値がないかもしれません。
- 最後に、提案されたテストについて、その機能や下位レベルのテストの実装に携わっている開発者と議論しましょう。
このチュートリアルでは、ログインのエンドツーエンドテストを書きます。たとえ下位レベルのテストで十分カバーされていたとしても、ほとんどのエンドツーエンドフローの最初のステップであり、一番理解しやすいからです。
DevOpsステージの特定
GitLab QAのエンドツーエンドテストは、DevOpsライフサイクルのさまざまなステージごとに整理されています。ステージごとにテストを配置する場所を決定し、テストがどの機能に属するかを決定し、ステージの下のサブディレクトリに配置します。
テストがEnterprise Editionのみの場合、テストはfeatures/ee
ディレクトリに作成されますが、同じDevOpsライフサイクルフォーマットに従います。
スケルトンテストの作成
このチュートリアルの最初の部分では、Manage ステージが所有する login をテストします。qa/specs/features/browser_ui/1_manage/login
内部で、ファイルbasic_login_spec.rb
を作成します。
内部context
。
内部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
何をテストするのか?
- ログインできますか?
- サインアウトできますか?
テストの方法は?
- 左サイドバーにユーザーアバターが表示されるか確認してください。
- 左サイドバーにユーザーアバターが表示されないかチェックします。
内部では、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/issue
にissues_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”に記載されています。
エンドツーエンドのテストマージリクエストテンプレート
新しいエンドツーエンドテストを提出する場合、マージに成功する前に必要な追加手順については、「新しいエンドツーエンドテスト」マージリクエスト記述テンプレートを使用してください。