以下の続きです。
システムアーキテクチャ
プロジェクトの構成
├─ src
├─ test
├─ java
| └─ jp.co.hoge.Project.E2ETest
| ├─ pageobject
| └─ steps
| └─ utils
└─ resources
└─ jp.co.hoge.Project.E2ETest
└─ feature files
- pagobject - 後述
- steps - 実際のテストを記述するファイルとなります。Gherkinで書かれた自然言語とコードの紐付けが行われます。
- utils - ユーティリティクラス群です。appiumサーバ作成用のクラスなどがあります。
- feature files - Gherkinでかかれたフィーチャーファイル群です。
PageObject
PageObjectは(テストとは関係なく)ページとユーザの関係を表したオブジェクトのことです。
以下条件を満たします。
- publicなメソッドはそのページが提供する論理的な処理を表す
- ページ内部の情報は公開しない
- テストで使用するアサーションはPageObject内に含まない
- メソッドはPageObjectを返す
- ページ全体を表す必要はない
- 同じアクションでも結果が異なる場合は異なるメソッドとして定義する
PageObjectサンプル
PageObjectは基本的に上記要件を満たしたものを言うのですが、開発の都合上完全に準拠する形にはしませんでした。
例えば今回PageObjectの基底クラスとしてBasePageというPageObjectを用意しています。
基本的に新たにPageObjectを作る際にはこのクラスを継承しています。
このBasePageには要素の存在確認用のpublicメソッドが実装されていますが、上の原則でいうメソッドはPageObjectsを返すに反してはいますが、便宜上存在確認は各PageObjectに実装することにしました。
/// PageObjectのExample
public class SearchPage extends BasePage {
public SearchPage(IOSDriver driver) {
super(driver);
}
@iOSXCUITFindBy(xpath = "//*[@name=\"検索\"]")
private IOSElement navigationBar;
@iOSXCUITFindBy(xpath = "//*[@name=\"アーティストをさがす\"]")
private IOSElement textSearchField;
@iOSXCUITFindBy(accessibility = "ランキング")
private IOSElement ranking;
...
public SearchResultPage searchText(String keyword) {
textSearchField.setValue(keyword);
driver.hideKeyboard();
return new SearchResultPage(driver);
}
public SearchSuggestPage showSuggest(String keyword) {
textSearchField.setValue(keyword);
return new SearchSuggestPage(driver);
}
public Boolean existsNavigationBar() {
return checkVisibilityOfElement(navigationBar);
}
...
Feature
シナリオを平文で書いたものです。ここで登場するのがGherkinと呼ばれる構文規則です。
Sample
Feature: 探すページを表示する
Scenario: 探すタブを押下する
Given アプリを起動し、さがす画面に遷移
Then さがす画面で、ヘッダに「さがす」と表示される
Steps Keyword
各ステップにはGiven, When, Then, And or Butというキーワードをつかうことができます。
ただし、これらはステップ定義を探す際に考慮されません。
Steps Argument
ステップ定義に引数を渡すことができます。ただし、使える型には制限があります。
https://cucumber.io/docs/cucumber/cucumber-expressions/#parameter-types
// example feature
Scenario: 音楽再生時のコントロールパネルを表示する
Given さがすタブをタップする
And テキスト検索から"米津玄師"を入力する
...
// example steps definision
@Given("テキスト検索から{string}を入力する")
public void テキスト検索から米津玄師を表示する(String keyword) {
searchResultPage = searchPage.searchText(keyword);
}
Skip Test
開発途中のステップなど、まだCI上でテストを実行して欲しくないFeatureがある際にignoreアノテーションをつけることによって該当テストの実行をスキップできます。
@ignore
Feature: 広告表示