- テストを書く前に
- エンド・ツー・エンドのテストが必要かどうかの判断
- DevOpsステージの特定
- スケルトン・テストの作成
- テストを書く
- コードの複製を削除
- リソースとページオブジェクトを使用したテストセットアップ
- Pagesオブジェクトの書き込み
- スペックの実行
初心者向けのE2Eテストの書き方ガイド
このチュートリアルでは、GitLab Community EditionとGitLab EnterpriseEditionのエンドツーエンド_(e2e)_テストの作成について学びます。
このチュートリアルの終わりには、以下のことができるようになります:
- エンド・ツー・エンドのテストが必要かどうかを判断します。
-
qa/
内のディレクトリ構造を理解しましょう。 - ログイン機能を検証する基本的なエンドツーエンドのテストを書いてください。
- 不足しているページオブジェクトライブラリを開発します。
テストを書く前に
テストを書く前に、GitLab Development Kit(GDK)が仕様を実行するように設定されている必要があります。 エンドツーエンドのテストです:
-
qa/
ディレクトリ内部にあります。 - 独立かつべき等であること。
- リソース(プロジェクト、イシュー、ユーザーなど)をアドホックに作成できます。
- UIとAPIのインターフェイスをテストし、APIを使用してUIテストを効率的に設定します。
エンド・ツー・エンドのテストが必要かどうかの判断
GitLab Community EditionとGitLab Enterprise Editionの両方のプロジェクトで、エンドツーエンドテストを書く前に特定の機能のコードカバレッジをチェックしてください。 ユニット、機能、インテグレーションの各レベルで十分なテストカバレッジが存在しますか? もし「はい」と答えたなら、エンドツーエンドテストは必要ありません。
GitLab におけるレベルごとのテストのディストリビューションについては、Testing Levelsを参照ください。
- テスト・レベルに関する文書の「正しいレベルでテストする方法」セクションを参照してください。
- 機能が変更される頻度をレビュアーがレビューします。 あまり頻繁に変更されない安定した機能は、低レベルのテストですでにカバーされている場合、エンドツーエンドのテストでカバーする価値がないかもしれません。
- 最後に、提案されたテストについて、その機能や下位レベルのテストの実装に携わる開発者と議論してください。
DevOpsステージの特定
GitLab QAのエンドツーエンドテストは、DevOpsライフサイクルのさまざまなステージごとに整理されています。ステージごとにテストを配置する場所を決め、テストがどの機能に属するかを決定し、ステージの下のサブディレクトリに配置します。
features/ee
ディレクトリに作成されますが、同じ DevOps ライフサイクル形式に従います。スケルトン・テストの作成
このチュートリアルの最初の部分では、Manageステージが所有するloginをテストします。qa/specs/features/browser_ui/1_manage/login
の内部で、ファイルbasic_login_spec.rb
を作成します。
外側のcontext
ブロック
スペックには、DevOpsのステージを示す内部context
。
# frozen_string_literal: true
module QA
context 'Manage' do
end
end
describe
ブロック
外側のcontext
の内部には、テストする機能を記述します。この場合、Login
。
# frozen_string_literal: true
module QA
context 'Manage' do
describe 'Login' do
end
end
end
it
ブロック(例)
すべてのテストスイートには、少なくとも一つのit
ブロック(例)が含まれています。 エンドツーエンドのテストを書き始める良い方法は、テストケースの記述をit
ブロックとして書くことです:
module QA
context 'Manage' do
describe 'Login' do
it 'can login' do
end
it 'can logout' do
end
end
end
end
テストを書く
重要なのは、”何をテストするのか?”、そしてさらに重要なのは、”どのようにテストするのか?”ということです。
ログインしてください。
# frozen_string_literal: true
module QA
context 'Manage' do
describe 'Login' 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
context 'Manage' do
describe 'Login' 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
何をテストするのですか?
- ログインできますか?
- ログアウトできますか?
どうやってテストするの?
- ユーザーアバターがトップナビゲーションに表示されるかどうかを確認します。
- ユーザーアバターがトップナビゲーションに表示されないか確認してください。
コードの複製を削除
sign_in
への呼び出しが重複しているので、テストのセットアップにbefore
ブロックを使うようにテストをリファクタリングしてください。
# frozen_string_literal: true
module QA
context 'Manage' do
describe 'Login' 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)
で、各例の前に実行され、各テストの開始時にログインするようにします。
リソースとページオブジェクトを使用したテストセットアップ
次に、Login以外のものをテストしてみましょう。Planステージが所有するイシューをテストするため、qa/specs/features/browser_ui/3_create/issues
にissues_spec.rb
というファイルを作成します。
# frozen_string_literal: true
module QA
context 'Plan' do
describe 'Issues' do
let(:issue) do
Resource::Issue.fabricate_via_api! do |issue|
issue.title = 'My issue'
issue.description = 'This is an issue specific to this test'
end
end
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のエンティティです。 他の例としては、以下のようなものがあります:
Pagesオブジェクトの書き込み
ページオブジェクトは、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
を定義し、Page Object から見えるようにします。
-#=> app/views/projects/issues/show.html.haml
.issuable-status-box.status-box.status-box-issue-closed{ ..., data: { qa_selector: 'closed_status_box' } }
スペックの実行
スペックを実行する前に確認してください:
- GDKがインストールされています。
- GDKはローカルではポート3000で動作しています。
- 追加のRSpecメタデータタグは適用されていません。
- 作業ディレクトリはGDK GitLabインストール内部
qa/
。
スペックを実行するには、以下のコマンドを実行します:
bundle exec bin/qa Test::Instance::All http://localhost:3000 -- <test_file>
<test_file>
:
-
qa/specs/features/browser_ui/1_manage/login/login_spec.rb
Loginの例を実行するとき。 -
qa/specs/features/browser_ui/2_plan/issues/issue_spec.rb
イシューの例を実行するとき。