はじめに
前回はkarateを使用してREST APIのテストを書きました。次はWebUIのテストの書き方をまとめます。REST APIの書き方とほとんど同じなので、前回と今回の2つを合わせるとkarateの魅力を感じられると思います。
環境
- IntelliJ:2020.1.3
- Java:11
- Gradle:7.0
環境作成
前回の環境作成と同じなので、そちらを確認してください。
テストソースの作成
前回と同様karateを使用するので、必要なものはJavaファイルとfeatureファイルの2つで変わりません。
Javaファイルの作成
Javaファイルは前回とほとんど同じです。ただ、今回はテスト前に環境変数をリセットするようにしていますが、あまり関係ないです。(最終的には設定ファイルで設定するはずです)
package com.karate.ui;
import com.intuit.karate.junit5.Karate;
import org.junit.jupiter.api.BeforeEach;
public class LoginPage {
@BeforeEach
public void beforeClass() {
// 環境変数をリセットする
System.setProperty("karate.env", "mock");
}
@Karate.Test
Karate loginPageTest() {
// loginPage.featureを読み取るように定義
return Karate.run("loginPage").relativeTo(getClass());
}
}
featureファイルの作成
次にfeatureファイルを作成します。ここが、前回と最も違うところです。
Webブラウザの設定
WebUIをテストするので、ブラウザを開くための設定をconfigure driver
にします。下の例ではchromeを使用すること以外は設定していないのですが、{ type: 'chrome', headless: true }
と設定するとヘッドレスモードで起動します。他にも様々な設定があるので公式を見てみてください。
Feature: UI操作
# driverの設定. chromeを設定
Background:
* configure driver = { type: 'chrome' }
テストシナリオの作成
ブラウザの設定が出来たので次はテストシナリオを描いていきます。書き方としては、前回と同様Gherkin形式で記載していきます。違う点はdriverにURLを指定する点、それぞれの処理をWebUI用の関数経由を使用する点の2つです。
Feature: UI操作
# driverの設定. chromeを設定
Background:
* configure driver = { type: 'chrome' }
Scenario: loginPage start
# URLを入力
Given driver 'http://localhost:3000'
# テキスト入力
And input('#my-account', 'dummy')
And input('#my-password', 'dummy')
# select選択(material-uiを使用しているので、karateのselectは使用できない)
And mouse('#simple-select').click()
# selectが開いた状態で下ボタンとエンターを押す。(bodyは特に対象を指定せずにWeb画面全体をさす)
And input('body', [Key.DOWN, Key.ENTER])
# クリックする
When mouse('[name=commit]').click()
# 画面遷移後にメッセージ文字列が表示されるかチェックする
Then match text('.MuiInputLabel-root') contains 'メッセージ'
テストの実行
テストの実行方法は前回と同じです。
テスト結果
実行するとブラウザが開いて自動的にWeb操作が行われます。
全ての結果がOKならこのようにpassedとなります。
seleniumとの比較
それぞれのソースコード
selenium
例で書いたのはユーザ名とパスワードを入力して画面遷移するソースを書きました。
package sample.selenium.test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.mockserver.client.MockServerClient;
import org.mockserver.junit.MockServerRule;
import org.mockserver.model.Header;
import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class TestProfile {
private static WebDriver driver = null;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe");
ChromeOptions options = new ChromeOptions();
driver = new ChromeDriver(options);
}
@Before
public void setUpBefore() throws Exception {
driver.get("http://localhost:3000");
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
driver.close();
}
@Test
public void loginCheck() {
WebElement myAccount = driver.findElement(By.id("my-account"));
myAccount.sendKeys("user");
WebElement myPassword = driver.findElement(By.id("my-password"));
myPassword.sendKeys("pass");
WebElement buttonElement = driver.findElement(By.id("input-button"));
buttonElement.sendKeys(Keys.ENTER);
String url = driver.getCurrentUrl();
assert(url).contains("http://localhost:3000/message");
}
}
karate
例で書いたのはユーザ名とパスワードを入力して画面遷移するソースを書きました。
Feature: UI操作
Background:
* configure driver = { type: 'chrome' }
Scenario: loginPage start
Given driver 'http://localhost:3000'
And input('#my-account', 'dummy')
And input('#my-password', 'dummy')
When mouse('[name=commit]').click()
Then waitForText('body', 'メッセージページ')
Then match driver.url == 'http://localhost:3000/message'
感想
seleniumは53行、karateは10行と行数は圧倒的にkarateの方が少なく書けました。また、ソースの見やすさもkarateの方が上なのかなと思います。一方でseleniumは昔からあるライブラリなので情報が豊富にありますが、karateはそこまで情報はありません。しかし、使い方を見ればわかるようにkarateは簡単に使えるので使うのであればkarateを使用した方が見やすく早くソースがかけるとおもいます。
終わりに
karateでWebUIのテストを書く方法をまとめました。結論としては、使用する関数が違うだけでREST APIのテストとほぼ書き方が変わらないことがわかりました。そのため、REST APIのテストとWebUIのテストをkarateにすることで学習するライブラリが1つで済み、ソース間で書き方の統一が図れてバックエンド用のテスター・フロントエンド用のテスターなど不合理な分け方をせずに、バックエンド・フロントエンド両方のテスターとして人を使えるので人に流動的に作業を割り当てが出来そうです。