サポート > Wagby Developer Network(R8) > E2Eテスト > 検索/一覧表示/一覧更新画面のテスト

検索/一覧表示/一覧更新画面のテストを行う方法を説明します。8.2.0

顧客モデル(customer)と、そのテストを行うソースコード一式を用意しました。

ここからテストコードを含むリポジトリをダウンロードできます。リストアすることでカスタマイズフォルダにテストコードが展開されます。

ダウンロードしたコンテンツに含まれる customize/test には次のファイルが含まれています。

ファイル 説明
java/jp/jasminesoft/wagby/tests/t001_Customer/AllTests.java junit TestSuiteクラス
java/jp/jasminesoft/wagby/tests/t001_Customer/CustomerTest.java 登録/更新/詳細表示画面のテストクラス
java/jp/jasminesoft/wagby/tests/t001_Customer/CustomerTest2.java 検索/一覧画面用テストクラス
java/jp/jasminesoft/wagby/tests/t001_Customer/CustomerTest3.java 一覧更新画面用テストクラス
java/jp/jasminesoft/wagby/tests/models/customer/Customer.java 登録/更新/詳細表示画面用モデルクラス
java/jp/jasminesoft/wagby/tests/models/customer/CustomerCp.java 検索条件画面用モデルクラス
java/jp/jasminesoft/wagby/tests/models/customer/CustomerLp.java 一覧画面用モデルクラス
java/jp/jasminesoft/wagby/tests/models/customer/CustomerUlp.java 一覧更新画面用モデルクラス

※ なおCustomerTest.javaとCustomer.javaはチュートリアルと同じ内容なので、ここでの説明は省略します。

実行

customize/test フォルダを含めビルドを行い、Eclipse でリフレッシュを行います。

jp.jasminesoft.wagby.tests.t001_Customer.AllTests クラスを実行すると、登録済みのテストが実行されます。

検索条件用モデルクラス

検索条件を格納するモデルクラスである CustomerCp.java は次のようになります。PageObject デザインパターンを使っています。

package jp.jasminesoft.wagby.tests.models.customer;

import javafx.scene.control.ComboBox;
import jp.jasminesoft.jfc.test.support.selenide.DateTextBox;
import jp.jasminesoft.jfc.test.support.selenide.ListBox;
import jp.jasminesoft.jfc.test.support.selenide.Postcode;
import jp.jasminesoft.jfc.test.support.selenide.WebConditionModel;
import jp.jasminesoft.jfc.test.support.selenide.WebModelitem;

/**
 * Customer モデルの検索条件部の情報を保持するクラス。
 *
 * @author JasmineSoft
 * @version $Revision$ $Date$
 */
public class CustomerCp extends WebConditionModel {

    /**
     * コンストラクタ。
     */
    public CustomerCp() {
        super("customer");
    }

    /**
     * customer/customerid
     * 検索画面では数値項目は範囲検索となる。
     * 範囲検索の下限項目(項目名末尾に "1jshparam" を付与)
     */
    public final WebModelitem<?> customerid1jshparam
            = new WebModelitem<>(this, "customerid1jshparam");

    /**
     * customer/customerid
     * 検索画面では数値項目は範囲検索となる。
     * 範囲検索の下限項目(項目名末尾に "2jshparam" を付与)
     */
    public final WebModelitem<?> customerid2jshparam
            = new WebModelitem<>(this, "customerid2jshparam");

    /** customer/name */
    public final WebModelitem<?> name
            = new WebModelitem<>(this, "name");

    /**
     * customer/customertype
     * 登録/更新画面では追記型リストボックスとして表現されるので、
     * {@link ComboBox} を用いるが、検索画面ではリストボックス
     * として表現されるので、{@link ListBox} を利用する。
     */
    public final ListBox customertype
            = new ListBox(this, "customertype");

    /** customer/title */
    public final WebModelitem<?> title
            = new WebModelitem<>(this, "title");

    /**
     * customer/zipcode */
    public final Postcode zipcode
            = new Postcode(this, "zipcode");

    /** customer/address */
    public final WebModelitem<?> address
            = new WebModelitem<>(this, "address");

    /**
     * customer/email
     * 検索画面では繰り返し項目扱いではないため、
     * {@link WebMultiModelitem} は使わない。
     */
    public final WebModelitem<?> email
            = new WebModelitem<>(this, "email");

    /** customer/tel */
    public final WebModelitem<?> tel
            = new WebModelitem<>(this, "tel");

    /**
     * customer/report/rdate
     * 検索画面ではコンテナ内項目は通常項目として
     * 扱われるため、{@link WebContainerModelitem} の定義は不要。
     */
    public final DateTextBox rdate1jshparam
            = new DateTextBox(this, "rdate1jshparam");

    /**
     * customer/report/rdate
     * 検索画面ではコンテナ内項目は通常項目として
     * 扱われるため、{@link WebContainerModelitem} の定義は不要。
     */
    public final DateTextBox rdate2jshparam
            = new DateTextBox(this, "rdate2jshparam");
}

親クラスのWebConditionModelは、検索条件を格納するモデルの雛形として WTF に含まれています。これを継承したクラス(ここでは CustomerCp) を開発者の方で用意します。PageObject デザインパターンを適用しており、各項目(およびその型)に対応した WebModelitem クラスを用意しています。

一覧表示用モデルクラス

一覧表示用モデルクラスである CustomerLp.java は次のようになります。PageObject デザインパターンを使っています。

package jp.jasminesoft.wagby.tests.models.customer;

import jp.jasminesoft.jfc.test.support.selenide.Postcode;
import jp.jasminesoft.jfc.test.support.selenide.RadioButton;
import jp.jasminesoft.jfc.test.support.selenide.WebListModel;
import jp.jasminesoft.jfc.test.support.selenide.WebModelitem;
import jp.jasminesoft.jfc.test.support.selenide.WebMultiModelitem;

/**
 * Customer モデルの一覧表示部の情報を保持するクラス。
 *
 * @author JasmineSoft
 * @version $Revision$ $Date$
 */
public class CustomerLp extends WebListModel<CustomerLp> {

    /**
     * コンストラクタ。
     */
    public CustomerLp() {
        super("customer");
    }

    /**
     * コンストラクタ。
     * @param index レコード番号
     */
    public CustomerLp(int index) {
        super("customer", index);
    }

    /** {@inheritDoc} */
    @Override
    protected CustomerLp newInstance(int idx) {
        return new CustomerLp(idx);
    }

    /** customer/customerid */
    public final WebModelitem<?> customerid
            = new WebModelitem<>(this, "customerid");

    /** customer/name */
    public final WebModelitem<?> name
            = new WebModelitem<>(this, "name");

    /** customer/customertype */
    public final RadioButton customertype
            = new RadioButton(this, "customertype");

    /** customer/title */
    public final WebModelitem<?> title
            = new WebModelitem<>(this, "title");

    /** customer/zipcode */
    public final Postcode zipcode
            = new Postcode(this, "zipcode");

    /** customer/address */
    public final WebModelitem<?> address
            = new WebModelitem<>(this, "address");

    /** customer/email */
    public final WebMultiModelitem<?> email
            = new WebMultiModelitem<>(this, "email");

    /** customer/tel */
    public final WebModelitem<?> tel
            = new WebModelitem<>(this, "tel");
}

親クラスのWebListModelは、一覧表示用のテストモデルの雛形として WTF に含まれています。これを継承したクラス(ここでは CustomerLp) を開発者の方で用意します。PageObject デザインパターンを適用しており、各項目(およびその型)に対応した WebModelitem クラスを用意しています。

一覧更新用モデルクラス

一覧更新画面用モデルクラスである CustomerUlp.java は次のようになります。PageObject デザインパターンを使っています。

package jp.jasminesoft.wagby.tests.models.customer;

import jp.jasminesoft.jfc.test.support.selenide.Postcode;
import jp.jasminesoft.jfc.test.support.selenide.RadioButton;
import jp.jasminesoft.jfc.test.support.selenide.WebModelitem;
import jp.jasminesoft.jfc.test.support.selenide.WebUpdateListModel;

/**
 * Customer モデルの一覧更新部の情報を保持するクラス。
 *
 * @author JasmineSoft
 * @version $Revision$ $Date$
 */
public class CustomerUlp extends WebUpdateListModel<CustomerUlp> {

    /**
     * コンストラクタ。
     */
    public CustomerUlp() {
        super("customer");
    }

    /**
     * コンストラクタ。
     * @param index レコード番号
     */
    public CustomerUlp(int index) {
        super("customer", index);
    }

    /** {@inheritDoc} */
    @Override
    protected CustomerUlp newInstance(int idx) {
        return new CustomerUlp(idx);
    }

    /** customer/customerid */
    public final WebModelitem<?> customerid
            = new WebModelitem<>(this, "customerid");

    /** customer/name */
    public final WebModelitem<?> name
            = new WebModelitem<>(this, "name");

    /** customer/customertype */
    public final RadioButton customertype
            = new RadioButton(this, "customertype");

    /** customer/title */
    public final WebModelitem<?> title
            = new WebModelitem<>(this, "title");

    /** customer/zipcode */
    public final Postcode zipcode
            = new Postcode(this, "zipcode");

    /** customer/address */
    public final WebModelitem<?> address
            = new WebModelitem<>(this, "address");

    // 繰り返し項目は一覧更新画面では対象外となり、表示されない。
    ///** customer/email */
    //public final WebMultiModelitem<?> email
    //        = new WebMultiModelitem<>(this, "email");

    /** customer/tel */
    public final WebModelitem<?> tel
            = new WebModelitem<>(this, "tel");
}

親クラスのWebUpdateListModelは、一覧更新用のテストモデルの雛形として WTF に含まれています。これを継承したクラス(ここでは CustomerUlp) を開発者の方で用意します。PageObject デザインパターンを適用しており、各項目(およびその型)に対応した WebModelitem クラスを用意しています。

テストコードは入力値を保持するモデルと、そのモデルを操作するテストコードという組み合わせになります。

顧客モデルの検索・一覧画面のテスト

ダウンロードしたファイルに含まれる CustomerTest2.java が検索と一覧表示画面のテストクラスです。この内容は次のとおりです。

package jp.jasminesoft.wagby.tests.t001_Customer;

import static com.codeborne.selenide.Condition.*;
import static com.codeborne.selenide.Selenide.*;
import static jp.jasminesoft.jfc.test.support.selenide.Operations.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import jp.jasminesoft.wagby.tests.models.customer.CustomerCp;
import jp.jasminesoft.wagby.tests.models.customer.CustomerLp;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

/**
 * 2. Customer モデルの検索・一覧画面のテスト
 *
 * @author JasmineSoft
 * @version $Revision$ $Date$
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class CustomerTest2 {

    /**
     * ログオン
     */
    @Test
    public void test00ログオン() {
        logon("admin", "wagby");
        pageTitle().shouldHave(exactText("メニュー"));
    }

    /**
     * 顧客情報検索へ遷移
     */
    @Test
    public void test01顧客情報検索へ遷移() {
        pageTitle().shouldHave(exactText("メニュー"));

        // メニューから顧客情報 検索画面へ遷移
        selectMenu("サービス", "顧客情報検索");
        pageTitle().shouldHave(exactText("顧客情報 検索"));
    }

    /**
     * 検索テスト
     */
    @Test
    public void test02検索テスト() {
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // WebConditionModel を継承した検索条件部を表すモデル。
        CustomerCp condition = new CustomerCp();

        // 以下、検索条件の入力。

        // 数値項目は検索画面では、下限部と上限部の2つの
        // 入力フィールドが用意されるので、対応する項目も
        // 2つ定義しておく。
        condition.customerid1jshparam.val("1");
        condition.customerid2jshparam.val("10000");

        // customertype 項目は登録/更新画面と検索画面では
        // 表示形式が異なるので注意。
        // 登録/更新画面では追記型リストボックスとして表現
        // されるので、ComboBox クラスを用いて定義されているが、
        // 検索画面ではリストボックスとして表現されるので、
        // ListBox クラスを項目クラスとして利用している。
        condition.customertype.val("地方公共団体");

        // 検索画面でも郵便番号と住所の同期が可能。
        condition.zipcode.val("901-2227").sync();

        // 住所項目: 郵便番号と同期後の値を確認。
        condition.address.shouldHave("沖縄県宜野湾市宇地泊");

        // 検索画面では繰り返し項目(WebMultiModelitem)ではなく
        // 通常項目(WebModelitem)として定義する。。
        condition.email.val("sales@jasminesoft.co.jp");

        // 日付項目も検索画面では、下限部と上限部に分かれている。
        // 検索画面でも DatePicker の利用が可能。
        condition.rdate1jshparam.datePicker()  // DetePicker を表示
                .nextMonth()          // 次の月へ
                .prevMonth()          // 前の月へ
                .nextYear()           // 次の年へ
                .prevYear()           // 前の年へ
                .selectDate(1);       // 1日を選択

        // 「検索の実行」ボタンをクリック。
        search();
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 検索結果件数の確認。
        $(".display_resultcount").shouldHave(text(
                "検索条件に合致したデータは1件見つかりました。"));
    }

    /**
     * 一覧表示のテスト
     */
    @Test
    public void test03一覧表示のテスト() {
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 「一覧画面へ」ボタンをクリック。
        clickListPageButton();
        pageTitle().shouldHave(exactText("顧客情報 一覧"));
        // 検索結果件数の確認。
        $(".display_resultcount").shouldHave(text(
                "1件中、1件目から1件目を表示しています。"));

        // WebListModel を継承した一覧表示部を表すモデル。
        CustomerLp list = new CustomerLp();
        // 1行目のデータを取得
        CustomerLp record01 = list.get(1);
        // テストを繰り返し実行するとズレてくるため、
        // 自動採番主キーの確認は行わないほうがよい。
        //record01.customerid.shouldHave("1000");

        // 通常項目
        record01.name.shouldHave("ジャスミン太郎");

        // ラジオボタン
        record01.customertype.shouldHave("地方公共団体");
        record01.title.shouldHave("一般");
        // 郵便番号
        record01.zipcode.shouldHave("901-2227");
        record01.address.shouldHave("沖縄県宜野湾市宇地泊");
        // 繰返し項目
        record01.email.shouldHave(
                "taro@jasminesoft.co.jp", "sales@jasminesoft.co.jp");
        record01.tel.shouldHave("098-890-6036");

        // 2件目のデータがあれば、以下のように取得する。
        //CustomerLp record02 = list.get(2);

        // 「詳細」ボタンをクリック。
        record01.clickDetailButton();
        pageTitle().shouldHave(exactText("顧客情報 詳細表示"));

        // 「検索画面へ」ボタンをクリック
        clickSearchPageButton();
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 1行目の「更新」ボタンをクリック。
        //record01.clickEditButton();
        //pageTitle().shouldHave(exactText("顧客情報 更新"));

        // 1行目の「コピー」ボタンをクリック。
        //record01.clickCopyButton();
        //pageTitle().shouldHave(exactText("顧客情報 コピー登録"));
    }

    /**
     * 検索条件リセットテスト
     */
    @Test
    public void test04検索条件リセットテスト() {
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 「リセット」ボタンをクリック。
        resetSearch();
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // メッセージの確認。
        $(".display_resultcount").shouldHave(exactText(
                "検索条件を入力してください。"));
    }

    /**
     * ログオフ
     */
    @Test
    public void test99ログオフ() {
        logoff();
    }
}

顧客モデルの一覧更新画面のテスト

ダウンロードしたファイルに含まれる CustomerTest3.java が一覧更新画面用のテストクラスです。この内容は次のとおりです。

package jp.jasminesoft.wagby.tests.t001_Customer;

import static com.codeborne.selenide.CollectionCondition.*;
import static com.codeborne.selenide.Condition.*;
import static com.codeborne.selenide.Selenide.*;
import static jp.jasminesoft.jfc.test.support.selenide.Operations.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import jp.jasminesoft.wagby.tests.models.customer.CustomerCp;
import jp.jasminesoft.wagby.tests.models.customer.CustomerLp;
import jp.jasminesoft.wagby.tests.models.customer.CustomerUlp;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

/**
 * 3. Customer モデルの一覧更新画面のテスト
 *
 * @author JasmineSoft
 * @version $Revision$ $Date$
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class CustomerTest3 {

    /**
     * ログオン
     */
    @Test
    public void test00ログオン() {
        logon("admin", "wagby");
        pageTitle().shouldHave(exactText("メニュー"));
    }

    /**
     * 顧客情報一覧更新へ遷移
     */
    @Test
    public void test01顧客情報一覧更新へ遷移() {
        pageTitle().shouldHave(exactText("メニュー"));

        // メニューから顧客情報 検索画面へ遷移
        selectMenu("サービス", "顧客情報検索");
        pageTitle().shouldHave(exactText("顧客情報 検索"));
    }

    /**
     * 前処理: 一覧更新対象データの絞り込み。
     */
    @Test
    public void test02一覧更新対象データの絞り込み() {
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 一覧更新対象データを検索画面で絞り込んでおく。
        CustomerCp condition = new CustomerCp();
        condition.name.val("ジャスミン太郎");

        // 「検索の実行」ボタンをクリック。
        search();
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 検索結果件数の確認。
        $(".display_resultcount").shouldHave(text(
                "検索条件に合致したデータは1件見つかりました。"));

        // 「一覧更新へ」ボタンをクリック。
        clickUpdateListPageButton();
        pageTitle().shouldHave(exactText("顧客情報 一覧更新"));
    }

    /**
     * 一覧更新のテスト
     */
    @Test
    public void test03一覧更新のテスト() {
        pageTitle().shouldHave(exactText("顧客情報 一覧更新"));

        // WebUpdateListModel を継承した一覧更新部を表すモデル。
        CustomerUlp updateList = new CustomerUlp();
        // 1行目のデータを取得
        CustomerUlp record01 = updateList.get(1);

        // 1行目の「コピー」ボタンをクリック。
        // 2行目のコピーされたデータが取得できる。
        CustomerUlp copyRecord02 = record01.clickCopyButton();

        // 名前を変更する。
        copyRecord02.name.val("ジャスミン次郎(※一覧更新画面で作成)");

        // 2行目の「コピー」ボタンをクリック。
        // 3行目の新規データが取得できる。
        CustomerUlp newRecord03 = copyRecord02.clickNewButton();

        newRecord03.name.val("ジャスミン三郎(※一覧更新画面で作成)");

        // ラジオボタン
        newRecord03.customertype.val("医療");
        newRecord03.title.val("外科部長");

        // 検索画面でも郵便番号と住所の同期が可能。
        newRecord03.zipcode.val("104-0054").sync();
        // 住所項目: 郵便番号と同期後の値を確認。
        newRecord03.address.shouldHave("東京都中央区勝どき");

        newRecord03.tel.val("03-6811-1173");

        //「保存」ボタンをクリック
        save();
        // メッセージチェック。
        infos().shouldBe(size(1));
        infos().shouldHave(exactTexts(
                "1件の顧客情報データを新規登録しました。"
                + "1件の顧客情報データをコピー登録しました。"));
        pageTitle().shouldHave(exactText("顧客情報 一覧"));
    }

    /**
     * 一覧更新結果の確認
     */
    @Test
    public void test04一覧更新結果の確認() {
        pageTitle().shouldHave(exactText("顧客情報 一覧"));

        // 「検索画面へ」ボタンをクリック
        clickSearchPageButton();
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 一覧更新対象データを検索画面で絞り込んでおく。
        CustomerCp condition = new CustomerCp();
        condition.name.val("(※一覧更新画面で作成)");

        // 「検索の実行」ボタンをクリック。
        search();
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 検索結果件数の確認。
        $(".display_resultcount").shouldHave(text(
                "検索条件に合致したデータは2件見つかりました。"));

        // 「一覧画面へ」ボタンをクリック。
        clickListPageButton();
        pageTitle().shouldHave(exactText("顧客情報 一覧"));
        // 検索結果件数の確認。
        $(".display_resultcount").shouldHave(text(
                "2件中、1件目から2件目を表示しています。"));

        CustomerLp list = new CustomerLp();
        // 1行目のデータの確認。
        CustomerLp record01 = list.get(1);

        record01.name.shouldHave("ジャスミン次郎(※一覧更新画面で作成)");
        record01.customertype.shouldHave("地方公共団体");
        record01.title.shouldHave("一般");
        record01.zipcode.shouldHave("901-2227");
        record01.address.shouldHave("沖縄県宜野湾市宇地泊");
        record01.email.shouldHave(
                "taro@jasminesoft.co.jp", "sales@jasminesoft.co.jp");
        record01.tel.shouldHave("098-890-6036");

        // 1行目のデータの確認。
        CustomerLp record02 = list.get(2);
        record02.name.shouldHave("ジャスミン三郎(※一覧更新画面で作成)");
        record02.customertype.shouldHave("医療");
        record02.title.shouldHave("外科部長");
        record02.zipcode.shouldHave("104-0054");
        record02.address.shouldHave("東京都中央区勝どき");
        record02.tel.shouldHave("03-6811-1173");
    }

    /**
     * 一覧更新での削除
     */
    @Test
    public void test05一覧更新での削除テスト() {
        pageTitle().shouldHave(exactText("顧客情報 一覧"));

        // 「検索画面へ」ボタンをクリック
        clickSearchPageButton();
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 検索条件が残っていることを確認。
        CustomerCp condition = new CustomerCp();
        condition.name.shouldHave("(※一覧更新画面で作成)");

        // 念の為、検索を再実行。
        search();
        pageTitle().shouldHave(exactText("顧客情報 検索"));

        // 検索結果件数の確認。
        $(".display_resultcount").shouldHave(text(
                "検索条件に合致したデータは2件見つかりました。"));

        // 「一覧更新へ」ボタンをクリック。
        clickUpdateListPageButton();
        pageTitle().shouldHave(exactText("顧客情報 一覧更新"));

        // 以下、表示されているデータ全てを削除する。
        CustomerUlp updateList = new CustomerUlp();
        // データ件数を取得。
        int rowSize = updateList.size();
        // データの件数分ループ処理を行う。
        for (int i = 1; i <= rowSize; i++) {
            // i行目の「削除」チェックボックスをクリック。
            updateList.get(i).clickDeleteCheckBox();
        }

        //「保存」ボタンをクリック
        save();
        pageTitle().shouldHave(exactText("顧客情報 一覧"));

        // メッセージチェック。
        infos().shouldHave(size(1));
        infos().shouldBe(exactTexts("2件の顧客情報データを削除しました。"));
    }

    /**
     * ログオフ
     */
    @Test
    public void test99ログオフ() {
        logoff();
    }
}