Qmonus Documents /
SDK Portal /8.E2E Testチュートリアル

E2E Tester チュートリアル

  • 0. はじめに
  • 1. シナリオを作成する
  • 2. 画面操作スクリプトを作成する
  • 3.1 実行パラメータ定義ファイルを作成する
  • 4.1 E2E テストを実行する
  • 4.2 動作確認をする
  • 0. はじめに

    E2E Testerは、SDKポータルが具備しているE2Eテストツールです。チュートリアルでは、GUIのサンプルコードに対してE2E Testerでシナリオ作成及び試験実施方法を習得することができます。

    後継の試験フレームワーク FrontTester について

    E2E Testerは後継としてFrontTesterがリリースされています。
    詳細はQmonus Documents / FrontTester /をご覧ください。


    試験対象のGUIについて

    チュートリアルで試験対象にするGUI サンプルは、以下のような雇用情報の一覧画面です。

    1. TOP 画面 (新規登録ボタン・詳細ボタン)

    2. 登録画面

    3. 詳細・編集画面 (編集ボタン・削除ボタン)

    GUI から 実行する API について

    画面上 から 実行する RESTful API は雇用情報を管理する Qmonus SDK Scenario とし、 Qmonus SDK Programming Guide Simple CRUD - シナリオ編 のサンプルを利用しています。

    作成する E2E テストのシナリオについて

    想定される画面操作・画面遷移を網羅するような条件分岐を作成し、画面入力値などを実行パラメータに設定・実行することで正常系・準正常系の UI テストに対応するようなシナリオを作成します。

    1. シナリオを作成する

    Tip

    💡 まずは、E2Eテスト実行の際に指定するシナリオ (ディレクトリ) を Home/ ディレクトリの直下に作成します。

    利用マニュアル [4.2 シナリオを作成する]を参照しながら、001sampleというscenario nameのシナリオを作成してください。

    シナリオ(ディレクトリ)を作成する手順は以上です。

    2. 画面操作スクリプトを作成する

    Tip

    💡 画面操作スクリプトには、試験対象であるGUIへのブラウザ操作を実装します。

    空のシナリオを作成したら、次項に従ってディレクトリの中に画面操作スクリプトを追加していきます。

    2.1 画面操作スクリプトの雛形を作成する

    Tip

    💡 E2E Testerでは、.js拡張子でファイルを新規作成すると画面操作スクリプトの雛形が自動作成されます。まずは雛形ファイルを作成していきましょう。

    1. 001sampleディレクトリに移動します。

    2. チュートリアルでは、以下の画面操作スクリプトを作成します。利用マニュアル4.3.1 ファイルを作成するを参照しながら、各スクリプトの雛形を作成してください。

      ファイル名 備考(これから実装するファイルの実装概要)
      00_login.js ログイン画面からトップ画面に遷移する
      01_create.js 登録ボタンの押下からemployment情報の入力、登録完了まで
      02_check_created.js 登録後に登録情報をチェックする
      03_update.js 編集ボタンの押下からemployment情報の入力、登録完了まで
      04_check_updated.js 変更後にemployment情報をチェックする
      05_delete.js 登録されているemployment情報を削除する

      雛形の作成が完了すると、001sampleシナリオの中に画面操作スクリプトが表示されます。

    2.2 画面操作スクリプトを実装する

    2.2.1 ユーザ操作の流れ

    チュートリアルではサンプルのGUI画面の動作に沿って以下の画面操作を実装します。

    • 雇用情報登録

      #1

      #2

      #3

      #4

      • 登録パラメータのセット数の分だけ #2 - #4 をループする

        # ユーザ操作内容 画面操作スクリプト
        1 TOP画面で登録ボタンを押下する 01_create.js
        2 登録画面でparamsにセットされた値を入力し、登録ボタンを押下する 01_create.js
        3 登録確認画面で登録ボタンを押下する 01_create.js
        4 入力した値で登録されたかTOP画面の一覧でチェックする 02_checked_create.js
    • 雇用情報変更

      #1

      #2

      #3

      #4

      • パラメータのセット数の分だけ #2 - #4 をループする

        # ユーザ操作内容 画面操作スクリプト
        1 TOP画面で変更する情報の鉛筆ボタンを押下する 03_update.js
        2 詳細画面で変更後の情報を入力し、変更ボタンを押下する 03_update.js
        3 変更確認画面で変更ボタンを押下する 03_update.js
        4 入力した値で変更されたかTOP画面の一覧でチェックする 03_update.js
    • 雇用情報削除

      #1

      #2

      #3

      • 登録した件数だけ #2 - #3 をループする

        # ユーザ操作内容 画面操作スクリプト
        1 TOP画面で変更する情報の鉛筆ボタンを押下する 05_delete.js
        2 詳細画面で削除ボタンを押下する 05_delete.js
        3 削除確認画面で削除ボタンを押下する 05_delete.js

    2.2.2 シナリオのフローチャート及びシナリオの実行パラメータの設計について

    E2E テストでは全ての UI 操作やアプリケーションの動作が仕様通りかチェックできるようなシナリオを作成します。チュートリアルでは雇用情報の一覧表示・登録・変更・削除の機能があり、シナリオの中に各機能をチェックできる画面操作スクリプトを用意していきます。画面操作スクリプトの作成ポイントとして以下2点があります。

    Tip

    💡 アプリケーションの UI が正しく機能するかすべて確認できるように、画面遷移のパターンや操作をすべて網羅するようなフローにする。

    Tip

    💡 そのため試験環境や試験内容で変わる画面遷移の分岐条件、および画面の入力値や選択値等は試験パラメータとして index.json に定義することを推奨する。 (詳細は後述の2. 実行パラメータを定義する参照)

    雇用情報登録の画面操作フロー

    雇用情報変更の画面操作フロー

    雇用情報削除の画面操作フロー

    2.2.3 サンプルコード

    以下が画面操作スクリプトのサンプルコードです。

    雇用情報管理画面ログイン 00_login.js
    js
    /** * frontal e2e test scenario * (puppeteer script wrapper) * * @param {Object} params : test parameters * @param {Object} root : puppeteer content root instance (page or frame instance) * @param {Object} actions : utility actions [ ex). actions.screenshot() ] * @param {Object} browser : puppeteer browser instance * @param {Object} page : puppeteer current page instance * @param {Object} frame : puppeteer current frame instance (when using the 'frameSelector' option ) * */ module.exports = async ( { params , root , page , actions } )=>{ //ログインページ await page.goto( params.url , {waitUntil: "domcontentloaded"} ); //let url = await page.url(); //loginpageの判定 let titleSelector = await root.$("head > title") let title = await (await titleSelector.getProperty('textContent')).jsonValue() //Login with Qmonus account if(title == "Login | Qmonus-SDK"){ //Login with Qmonus account await root.click('#provider-selector > div > a:nth-child(3)') // ログインボタンをクリックする await root.waitFor(300) // 画面表示の待機 //Username let Username = await root.$("#axis-loginform > div.col-sm-6 > div.container > div:nth-child(1) > input") await Username.type(params.Username) // params.Username に設定された ユーザ名を入力する //password let password = await root.$("#axis-loginform > div.col-sm-6 > div.container > div:nth-child(2) > input") await password.type(params.password) // params.password に設定されたパスワードを入力する //ログイン await root.click("#axis-loginform > div.col-sm-6 > div.container > div:nth-child(6) > button") await root.waitFor(1000) await actions.screenshot( "Login Success" ); // エビデンスとしてスクリーンショットを保存する } }
    雇用情報登録機能 01_create.js
    js
    const commonUtils = require('../_common_util') module.exports = async ( { params , root , page , actions } )=>{ for (let i = 0;i<params.employment.create.length ; i ++){ // パラメータにセットされた登録件数だけループ await root.waitFor(1000)                                                            // 画面表示待ち //get input data let input_data = params.employment.create[i] // 試験パラメータの取得 //go to top let top_btn = await root.$("#return-top") // TOPボタンのセレクタを取得 await top_btn.click()                                          // TOPボタンをクリック await root.waitFor(500) // TOP画面の遷移を待機 // go to create page   <-- 新規登録ボタンを押下して登録画面に画面遷移 let go_create_btn = await root.$("#create-btn") await go_create_btn.click() await root.waitFor(500) //get input fields  <-- 入力フォームのセレクタを取得 let firstname = await root.$("#input-firstname") let lastname = await root.$("#input-lastname") let email = await root.$("#input-email") let salaryRequirements = await root.$("#input-salaryRequirements") //input data  <-- 入力フォームに雇用情報を入力 await firstname.type(input_data.firstName.value) await lastname.type(input_data.lastName.value) await email.type(input_data.email.value) //select salary <-- プルダウンから雇用情報を選択 let salaryRequirements_btn = await root.$("#input-salaryRequirements") await salaryRequirements_btn.click() await page.$$('.v-menu__content.theme--light.menuable__content__active .v-list-item').then(el => el[commonUtils.check_salary(input_data.salaryRequirements.value)].click()) await root.waitFor(1000) await actions.screenshot( "input-list_" +i); // エビデンスとしてスクリーンショットを取得 let create_btn = await root.$("#create-btn") if(params.employment.create[i].expect_successed){  // APIcallが正常応答する場合の画面操作 await actions.logger("正常") //submit data <-- 登録ボタンを押下 await create_btn.click() //confirm data <-- 確認ボタンを押下 await root.waitFor(1000) let confirm_btn = await root.$("#confirm-btn") await confirm_btn.click() await root.waitFor(1000) // 一覧画面への遷移を待機 await actions.screenshot( "move_summary" ); }else{ await actions.logger("準正常") if(! input_data.expect_api_error){  // 画面の入力バリデーションでエラーになる場合の画面操作 //valid firstName <-- firstName入力値が画面エラーの場合エラーメッセージを取得 let selector_valid_msg_firstName = await root.$("#app > div.v-application--wrap > main > div > div > div:nth-child(2) > div > form > div:nth-child(1) > div > div.v-text-field__details > div > div > div") let valid_msg_firstName = await (await selector_valid_msg_firstName.getProperty('textContent')).jsonValue() await actions.logger(valid_msg_firstName) //valid lastName <-- lastName入力値が画面エラーの場合エラーメッセージを取得 let selector_valid_msg_lastName = await root.$("#app > div.v-application--wrap > main > div > div > div:nth-child(2) > div > form > div:nth-child(2) > div > div.v-text-field__details > div > div > div") let valid_msg_lastName = await (await selector_valid_msg_lastName.getProperty('textContent')).jsonValue() await actions.logger(valid_msg_lastName) await root.waitFor(1000) await actions.screenshot( "valid name_" + i); }else{                                                         // APIcallがエラー応答する場合の画面操作 //submit data <-- 登録ボタンを押下 await create_btn.click() //confirm data <-- 確認ボタンを押下 await root.waitFor(500) let confirm_btn = await root.$("#confirm-btn") await confirm_btn.click() //error message <-- APIエラーメッセージを取得 let selector_error_message = await root.$("#error_msg") let error_message = await (await selector_error_message.getProperty('textContent')).jsonValue() await actions.logger(error_message) await root.waitFor(1000) await actions.screenshot("error_" + i); let cloese_error_btn = await root.$("#close_error_dialog") await cloese_error_btn.click() await root.waitFor(500) await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] }); } } } }
    雇用情報登録機能 02_check_created.js
    js
    const commonUtils = require('../_common_util') module.exports = async ( { params , root , page , actions } )=>{ await actions.logger(commonUtils.created_count(params.employment.create) +"ループ"); //go to top let top_btn = await root.$("#return-top") // TOPボタンのセレクタを取得 await top_btn.click()  // TOPボタンをクリック await root.waitFor(500) // TOP画面の遷移を待機 await actions.screenshot( "create_check_summary"); // エビデンスとしてスクリーンショットを取得 //selector table let selector_table_rows_str = "#data-table > div.v-data-table__wrapper > table > tbody > tr" let selector_table_rows = await page.$$(selector_table_rows_str) await actions.logger("表示件数 : " + selector_table_rows.length) //create チェック <-- 登録情報の値をチェック for (let i = 0;i < params.employment.create.length; i ++){ // 作成した件数だけループ let input_data={} if(!params.employment.create[i].expect_successed){ // 準正常系の試験データの場合スキップ await actions.logger("準正常") continue; }else{ // 正常系の試験データの場合は比較用に登録時の入力値を保存 await actions.logger("正常") //get input data input_data = params.employment.create[i] await actions.logger("正常系チェックデータ" + input_data.email.value) } for (let k = 1;k<selector_table_rows.length +1 ; k ++){ // 一覧に表示された件数だけループ let selector_email_str = "#data-table > div.v-data-table__wrapper > table > tbody > tr:nth-child(" + k + ") >" + "td:nth-child(5)" let selector_email = (await root.$(selector_email_str)) let value_email = await (await selector_email.getProperty('textContent')).jsonValue() if(value_email == input_data.email.value){ // emailが一致する行の情報を登録情報と比較 await actions.logger(k + "件目 - ") // //各パラメータ確認 for (let j = 3; j < 7; j++) { //get summary value let selector_str = "#data-table > div.v-data-table__wrapper > table > tbody > tr:nth-child(" + k + ") >" + "td:nth-child(" + j + ")" let selector = (await root.$(selector_str)) let value = await (await selector.getProperty('textContent')).jsonValue() //compare value for (let key in input_data) { if (input_data[key].id == (j - 2)){ if ( !(input_data[key].value == value)){ // 登録情報と表示が一致する場合エラー //error throw new Error("key- " + key + "にて"+input_data[key].value+"と"+value+"が一致しません") }else{ //Success await actions.logger("Success-" + key); } } } } break; } } } }
    雇用情報変更機能 03_update.js
    js
    const commonUtils = require('../_common_util') // 共通関数の呼び出すための参照 module.exports = async ( { params , root , page , actions } )=>{ for (let i = 0;i<params.employment.update.length ; i ++){ // 更新件数だけループ //get input data let input_data = params.employment.update[i] // get entryNumber <-- TOP画面の1行目のentry_numberを取得 let selector_entry_number_str = "#data-table > div.v-data-table__wrapper > table > tbody > tr > td:nth-child(2)" let selector_entry_number = (await root.$(selector_entry_number_str)) let entry_number = await (await selector_entry_number.getProperty('textContent')).jsonValue() input_data.entry_number = entry_number; await actions.logger("EntryNumber : " + entry_number) // go to update page <-- 詳細ボタンを押下 let go_update_btn = await root.$(" #data-table > div.v-data-table__wrapper > table > tbody > tr > td:nth-child(1) > button"); await go_update_btn.click(); await root.waitFor(1000); await actions.screenshot( "move_updatePage_" +i); const firstname = await page.$('#input-firstname'); // 変更情報を入力 (firstName) await firstname.click({ clickCount: 3 }) await firstname.type(input_data.firstName.value); const lastname = await page.$('#input-lastname'); // 変更情報を入力 (lastName) await lastname.click({ clickCount: 3 }) await lastname.type(input_data.lastName.value); const email = await page.$('#input-email'); // 変更情報を入力 (email) await email.click({ clickCount: 3 }) await email.type(input_data.email.value); //select salary <-- salary情報をプルダウン選択 let salaryRequirements_btn = await root.$("#input-salaryRequirements") await salaryRequirements_btn.click() await page.$$('.v-menu__content.theme--light.menuable__content__active .v-list-item').then(el => el[commonUtils.check_salary(input_data.salaryRequirements.value)].click()) await root.waitFor(1000); await actions.screenshot( "input-list_" + i); // go to confirm dailog <-- 変更ボタンを選択して確認画面を表示 let update_submit_btn = await root.$("#update-btn"); if(params.employment.update[i].expect_successed){ // 正常系試験の場合確認画面で登録ボタンを押下 await actions.logger("正常") await update_submit_btn.click(); // confirm await root.waitFor(500); let update_confirm_btn = await root.$("#update-confirm-btn"); await update_confirm_btn.click(); await root.waitFor(3000); await actions.screenshot( "updated_" + i); }else{ await actions.logger("準正常") if(! input_data.expect_api_error){ // 画面の入力エラーの場合エラーメッセージを取得 //valid firstName let selector_valid_msg_firstName = await root.$("#app > div > main > div > div > div:nth-child(2) > form > div:nth-child(3) > div.col.col-3 > div > div > div.v-text-field__details > div > div > div") let valid_msg_firstName = await (await selector_valid_msg_firstName.getProperty('textContent')).jsonValue() await actions.logger(valid_msg_firstName) //valid lastName let selector_valid_msg_lastName = await root.$("#app > div > main > div > div > div:nth-child(2) > form > div:nth-child(4) > div.col.col-3 > div > div > div.v-text-field__details > div > div > div") let valid_msg_lastName = await (await selector_valid_msg_lastName.getProperty('textContent')).jsonValue() await actions.logger(valid_msg_lastName) await root.waitFor(1000) await actions.screenshot( "valid name_" + i); }else{ // APIエラーを返却する場合エラーメッセージを取得 //submit data await update_submit_btn.click() //confirm data <-- 確認画面で変更ボタンを押下 await root.waitFor(500) let update_confirm_btn = await root.$("#update-confirm-btn"); await update_confirm_btn.click(); //error message <-- エラーメッセージを表示 let selector_error_message = await root.$("#error_msg_update") let error_message = await (await selector_error_message.getProperty('textContent')).jsonValue() await actions.logger(error_message) await root.waitFor(1000) await actions.screenshot( "error_" + i); let close_error_btn = await root.$("#close_error_dialog_update") // エラー表示を閉じる await close_error_btn.click() await root.waitFor(1000) await actions.screenshot( "back_to_top_page"); await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] }); } } // CHECK UPDATED <-- 変更した情報を一覧画面でチェック // go to top <-- 一覧画面で let top_btn = await root.$("#return-top") await top_btn.click() await root.waitFor(500) await actions.screenshot( "update_check_summary"); if(!params.employment.update[i].expect_successed){ await actions.logger("準正常") continue; }else{ await actions.logger("正常") } // table rows let selector_table_rows_str = "#data-table > div.v-data-table__wrapper > table > tbody > tr" let selector_table_rows = await page.$$(selector_table_rows_str) await actions.logger("表示件数 : " + selector_table_rows.length) await actions.logger("正常系チェックデータ" + input_data.entry_number) // check updated for (let k = 1;k < selector_table_rows.length +1; k ++){ let selector_entry_number_str = "#data-table > div.v-data-table__wrapper > table > tbody > tr:nth-child(" + k + ") >" + "td:nth-child(2)" let selector_entry_number = await root.$(selector_entry_number_str) let value_entry_number = await (await selector_entry_number.getProperty('textContent')).jsonValue() if(value_entry_number == input_data.entry_number){ await actions.logger(k + "件目 - ") //各パラメータ確認 for (let j = 3; j < 7; j++) { //get summary value let selector_str = "#data-table > div.v-data-table__wrapper > table > tbody > tr:nth-child(" + k + ") > " + "td:nth-child(" + j + ")" let selector = (await root.$(selector_str)) let value = await (await selector.getProperty('textContent')).jsonValue() //compare value for (let key in input_data) { if (input_data[key].id == (j - 2)){ if ( !(input_data[key].value == value)){ //error throw new Error("key- " + key + "にて入力値"+input_data[key].value+"と一覧結果"+value+"が一致しません") }else{ //Success await actions.logger("Success-" + key); } } } } break; } } } }
    雇用情報削除機能 04_delete.js
    js
    const commonUtils = require('../_common_util') module.exports = async ( { params , root , page , actions } )=>{ for (let i = 0;i<params.employment.create.length ; i ++){ // パラメータにセットされた登録件数だけループ await root.waitFor(1000)                                                            // 画面表示待ち //get input data let input_data = params.employment.create[i] // 試験パラメータの取得 //go to top let top_btn = await root.$("#return-top") // TOPボタンのセレクタを取得 await top_btn.click()                                          // TOPボタンをクリック await root.waitFor(500) // TOP画面の遷移を待機 // go to create page   <-- 新規登録ボタンを押下して登録画面に画面遷移 let go_create_btn = await root.$("#create-btn") await go_create_btn.click() await root.waitFor(500) //get input fields  <-- 入力フォームのセレクタを取得 let firstname = await root.$("#input-firstname") let lastname = await root.$("#input-lastname") let email = await root.$("#input-email") let salaryRequirements = await root.$("#input-salaryRequirements") //input data  <-- 入力フォームに雇用情報を入力 await firstname.type(input_data.firstName.value) await lastname.type(input_data.lastName.value) await email.type(input_data.email.value) //select salary <-- プルダウンから雇用情報を選択 let salaryRequirements_btn = await root.$("#input-salaryRequirements") await salaryRequirements_btn.click() await page.$$('.v-menu__content.theme--light.menuable__content__active .v-list-item').then(el => el[commonUtils.check_salary(input_data.salaryRequirements.value)].click()) await root.waitFor(1000) await actions.screenshot( "input-list_" +i); // エビデンスとして画面をスクリーンショット let create_btn = await root.$("#create-btn") if(params.employment.create[i].expect_successed){  // APIcallが正常応答する場合の画面操作 await actions.logger("正常") //submit data <-- 登録ボタンを押下 await create_btn.click() //confirm data <-- 確認ボタンを押下 await root.waitFor(1000) let confirm_btn = await root.$("#confirm-btn") await confirm_btn.click() await root.waitFor(1000) // 一覧画面への遷移を待機 await actions.screenshot( "move_summary" ); }else{ await actions.logger("準正常") if(! input_data.expect_api_error){  // 画面の入力バリデーションでエラーになる場合の画面操作 //valid firstName <-- firstName入力値が画面エラーの場合エラーメッセージを取得 let selector_valid_msg_firstName = await root.$("#app > div.v-application--wrap > main > div > div > div:nth-child(2) > div > form > div:nth-child(1) > div > div.v-text-field__details > div > div > div") let valid_msg_firstName = await (await selector_valid_msg_firstName.getProperty('textContent')).jsonValue() await actions.logger(valid_msg_firstName) //valid lastName <-- lastName入力値が画面エラーの場合エラーメッセージを取得 let selector_valid_msg_lastName = await root.$("#app > div.v-application--wrap > main > div > div > div:nth-child(2) > div > form > div:nth-child(2) > div > div.v-text-field__details > div > div > div") let valid_msg_lastName = await (await selector_valid_msg_lastName.getProperty('textContent')).jsonValue() await actions.logger(valid_msg_lastName) await root.waitFor(1000) await actions.screenshot( "valid name_" + i); }else{                                                         // APIcallがエラー応答する場合の画面操作 //submit data <-- 登録ボタンを押下 await create_btn.click() //confirm data <-- 確認ボタンを押下 await root.waitFor(500) let confirm_btn = await root.$("#confirm-btn") await confirm_btn.click() //error message <-- APIエラーメッセージを取得 let selector_error_message = await root.$("#error_msg") let error_message = await (await selector_error_message.getProperty('textContent')).jsonValue() await actions.logger(error_message) await root.waitFor(1000) await actions.screenshot("error_" + i); let cloese_error_btn = await root.$("#close_error_dialog") await cloese_error_btn.click() await root.waitFor(500) await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] }); } } } }

    2.2.3 画面操作スクリプトの中でのパラメータの呼び出し方法について

    E2E テストを実行するときに指定するパラメータは index.json のparamsというパラメータの中に定義します。試験対象のURLをurlというパラメータにする場合は例 1 のように index.json に定義します。画面操作スクリプトの中では、下記の様に呼び出すことができます (例2)。index.json の詳細については後述の2. 実行パラメータを定義するを参照ください。

    json
    // index.json 例(1) { "params": { "url": "https://www.sample.com/" } }
    jsx
    // 画面操作スクリプト 例(2) // ログイン画面のURLにページ遷移する await page.goto( params.url , {waitUntil: "domcontentloaded"} );

    2.2.4 画面操作スクリプトの言語について

    puppeteerというNode.js ライブラリを利用したjavascriptで実装します。また、E2E Tester でラッパーしているpuppeteer関数もあるため詳細は利用マニュアル4.3.2 画面操作スクリプトを実装するを参照ください。

    3. 実行パラメータを定義する

    Tip

    💡 E2Eテスト実行の際に指定するパラメータを定義します。index.json という名称でJSON形式のファイルを作成し、シナリオのパラメータや、E2Eテスト実行環境の設定値を定義していきます。

    3.1 実行パラメータ定義ファイルを作成する

    Tip

    💡 index.json という名前でファイルを新規作成すると、パラメータ定義ファイルの雛形を作成することができます。まず index.json ファイルを作成し、雛形に沿って実装していきます。

    1. 001sampleディレクトリに移動します。

    2. 利用マニュアル4.4.1 index.json を作成するを参照しながら、実行パラメータの定義ファイルを作成してください。作成が完了すると、以下のように雛形がエディタに表示されます。

    3. index.json に定義可能なパラメータは利用マニュアル [4.4.3 index.json に設定可能なパラメータの一覧] を参照ください。paramsには、試験環境のURL や認証情報、画面の入力値など、試験内容・試験環境で変化する値をパラメータとして追加することを推奨しています。チュートリアルでは、params の配下に以下のパラメータを用意します。

    json
    "params": { "url": "https://api-front-2...", # API Front のURL "Username": "test", # API Front の login username "password": "test", # API Front の login password "query": {}, "employment": { # employment 情報に関するパラメータをこの中で定義する "create": [ # 0001_create.js/ 0002_check_created.js に必要なパラメータをこの中で定義する. 空の場合、create に関する画面操作スクリプトの実行をスキップする { "expect_successed": true, # 正常系のフラグ。正常系テストの場合はtrue "expect_api_error": false, # 画面の準正常のフラグ。API実行前に画面で入力値バリデーションエラーと判定するが期待値の場合true "firstName": { "value": "Ray", # firstName欄の入力値 "id": "1" # 登録データのチェックに必要なパラメータ }, "lastName": { "value": "Amuro", # lastName欄の入力値 "id": "2" # 登録データのチェックに必要なパラメータ }, "email": { "value": "amuroray@uc.com", # email欄の入力値 "id": "3" # 登録データのチェックに必要なパラメータ }, "salaryRequirements": { "value": "200000", # salaryRequirements欄の入力値 "id": "4" # 登録データのチェックに必要なパラメータ } } ], "update": [ # 0003_update.js/ 0004_check_updated.js に必要なパラメータをこの中で定義する { # createと同様のパラメータ } ] } },

    4. E2E テストを実行する

    Tip

    💡 E2E テストの実行手段は、(1) E2E Testerから実行、または (2) ローカル環境からAPIを呼び出す2パターン存在します。チュートリアルでは (1) の手段を紹介します。(2) については利用マニュアルを参照ください。

    4.1 E2E テストを実行する

    作成した001sampleシナリオは、[Test Console] から指定してE2Eテスト実行することができます。

    Tip

    💡 必要な試験のパラメータの値を指定し、E2E テストを実行します。前項 2.1 章で作成した index.json の値が初期表示されますが、変更することも可能です。

    1. Test Console の [Start New Test] を押下します。

    2. ポップアップ表示された Select E2E Scenario 画面の [Scenario Name] からシナリオ001sampleを選択し、[Submit] ボタンを押下します。

    3. ポップアップ表示された Select New Test 画面にて、3ステップで実行パラメータをセットしていきます。

      [Test Parameters] > [Test Scenario Parameters] はシナリオのパラメータを入力する欄です。初期表示では index.json のparamsのデフォルト値が表示されています。今回はデフォルトの値でurlキーに対象GUIのURLを設定します。URLは、Qmonus Value Stream で環境作成した際の Api Front のURL です。

    4. [Test Condition] を押下すると、 [Test Conditions] に E2E テストの実行オプションを設定することができます。初期表示では2.1章で index.json を作成した際に自動生成された設定パラメータ defaultOptionsのデフォルト値が表示されており、こちらも今回はデフォルト値で実行するため、編集しません。

    5. [Test Description] > [description] に 実行するE2E テストの補足 (任意)を設定し、[Test Start] ボタンを押下すると試験が開始されます。チュートリアルではtutorial take1と入力してみましょう。

    6. E2E テストが開始すると実行状況を確認することができます。実行中の E2E Test は、実行時間昇順に上から表示されます。

      Tip

      💡 前項でdescriptionパラメータに設定したtutorial take1はシナリオ名001sampleの下に表示されています。実行ごとに補足を表示したい場合に使用します。

      正常に完了すると、[Status] にcompleted、[End] に終了時間、[Progress] に100%と表示されます。

      E2E テストを実行する手順は以上です。

    4.2 動作確認をする

    4.2.1 実行ログを確認する

    E2E Tester の実行ログは [Evidence] で確認することができます。

    1. 歯車ボタンを押下します。

    2. ポップアップ表示された test logs 画面で実行ログを確認することができます。また画面操作スクリプト内でawait actions.logger()を実装した場合もここに表示されます。

    実行ログを確認する手順は以上です。

    4.2.2 スクリーンショットを確認する

    画面操作スクリプト内でawait actions.screenshot()を実装すると [Evidence] に順にスクリーンショットが並び、クリックすると確認することができます。

    1. [Evidence] のナンバリングされたスクリーンショットボタンを押下します。

    2. ポップアップ表示でスクリーンショットを確認することができます。また、左右のボタンで前後のスクリーンショットを確認することができます。

    スクリーンショットを確認する手順は以上です。

    4.3.3 エラーログを確認する

    Tip

    💡 E2E Test の実行中にエラーが生じた場合、以下の箇所からエラーログを確認することができます。

    • [info] ボタン > test Details 画面の [error]

    • 歯車ボタン > test logs 画面の [test logs]

    エラーログを確認する手順は以上です。

    4.3.4. エビデンスを取得する

    E2E テストの実行結果は、[Evidence] からローカル環境にダウンロードすることができます。
    エビデンスには実行情報、スクリーンショット、及びログファイルが含まれます。詳細は利用マニュアル6.5 エビデンスを取得するをご確認ください。

    9.起動パラメータ
    7.End To End Test