趣旨

画面操作を伴う自動テストのコツを思い出しやすくするためメモしておく

テストコードにseleniumの自動操作をいれるが、そうなると、サーバの実行プロセスとは別になり、ブレークポイントで停止させる難易度が跳ね上がる。

ところどころ間違いがあるかもしれないが、どうやっていたか、少し思い出しながらメモを書いていく

はてサーバは別途デバッグ起動しておくんだったかな。。。?

という感じで記憶がやばい、いろいろ試行錯誤してして記憶が混濁してしまった。動いたときに、すぐに成功のコツをメモしないとこうなってしまうんだな。以後気を付けよう

背景

AIがすぐに作ってくれなかったのでやり方のコツをメモしておく

環境構築

必要な依存関係

pom.xmlに以下の依存関係を追加する:

selenium-java
junit-jupiter
webdrivermanager

pomに各jarのバージョン変数を追加

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
               <lombok.version>1.18.36</lombok.version>
               <selenium.version>4.18.0</selenium.version>
               <junit.jupiter.version>5.10.2</junit.jupiter.version>
               <assertj.version>3.25.3</assertj.version>
               <webdrivermanager.version>5.7.0</webdrivermanager.version>
	</properties>

依存をpomに追加

                               <dependency>
                                       <groupId>org.seleniumhq.selenium</groupId>
                                       <artifactId>selenium-java</artifactId>
                                       <version>${selenium.version}</version>
                                       <scope>test</scope>
                               </dependency>
                               <dependency>
                                       <groupId>org.junit.jupiter</groupId>
                                       <artifactId>junit-jupiter</artifactId>
                                       <version>${junit.jupiter.version}</version>
                                       <scope>test</scope>
                               </dependency>
                               <dependency>
                                       <groupId>io.github.bonigarcia</groupId>
                                       <artifactId>webdrivermanager</artifactId>
                                       <version>${webdrivermanager.version}</version>
                                       <scope>test</scope>
                               </dependency>
                               <dependency>
                                       <groupId>org.apache.httpcomponents.client5</groupId>
                                       <artifactId>httpclient5</artifactId>
                                       <version>5.2.1</version>
                                       <scope>test</scope>
                               </dependency>
                               <dependency>
                                       <groupId>commons-io</groupId>
                                       <artifactId>commons-io</artifactId>
                                       <version>2.11.0</version>
                                       <scope>test</scope>
                               </dependency>

これらを設定したら、

mvn dependency:resolve

コマンドを実行

追加するGUIのツール誰か作ってほしい

テストクラスの基本構造

アノテーション

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
- ランダムポートでSpringBootアプリケーションを起動
@TestPropertySource
- テスト用のプロパティを設定

必要なフィールド

@LocalServerPort
- SpringBootが割り当てたポート番号を取得
WebDriver
- Seleniumのブラウザ操作用インスタンス
WebDriverWait
- 要素の待機処理用

Page Objectパターン

画面操作をカプセル化するためのパターン

- 各画面の操作をクラスとして分離
- テストコードの可読性と保守性が向上

実装例

public class SearchPage {
    private WebDriver driver;
    private WebDriverWait wait; 

    public SearchPage(WebDriver driver, WebDriverWait wait) {
        this.driver = driver;
        this.wait = wait;
    }

    public DetailPage searchAndOpenDetail(String receptionNo) {
        // 画面操作のロジック
        return new DetailPage(driver, wait);
    }
}

テスト実装のポイント

セットアップ処理

@BeforeEach内で実施
- WebDriverManagerでブラウザドライバセットアップ
- ブラウザウィンドウの最大化
- ログイン処理

例: 大体同じような処理をすると思うので、よく使う処理をabstractクラスに書いておいて、テストクラスを作るときには、このクラスをextendsするようにすると、記述が簡単になるだろう。

public abstract class BaseSeleniumTest {
    protected WebDriver driver;
    protected WebDriverWait wait;
    protected String originalWindow;

    @BeforeEach
    public void setUp() {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        driver.manage().window().maximize();

        // ログインページにアクセス
        driver.get("http://localhost:8080/xxx/login");

        // ログインボタンを見つけてクリック
        WebElement loginButton = wait.until(ExpectedConditions.presenceOfElementLocated(
            By.cssSelector(".xxx")));
        loginButton.click();

        // 管理画面が表示されるまで待機
        wait.until(ExpectedConditions.titleContains("タイトル文言など"));

        // 元のウィンドウハンドルを保存
        originalWindow = driver.getWindowHandle();
    }
    @AfterEach
    public void tearDown() {
        // 新しいウィンドウが開いている場合は閉じる
        Set<String> windows = driver.getWindowHandles();
        if (windows.size() > 1) {
            windows.stream()
                .filter(handle -> !handle.equals(originalWindow))
                .forEach(handle -> {
                    driver.switchTo().window(handle);
                    driver.close();
                });
            // 元のウィンドウに戻る
            driver.switchTo().window(originalWindow);
        }

        if (driver != null) {
            driver.quit();
        }
    }
}

クリーンアップ処理

@AfterEach内で実施
- ブラウザの終了(driver.quit())

要素の待機

WebDriverWait?を使用して要素の表示を待機

wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".selector")));

テスト実行の設定

CIなどで、Seleniumを使った自動テストを自動実行の対象から外したい場合があると思うがその場合の指定をしておく。

maven-surefire-plugin

テストの実行制御

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <excludedGroups>selenium</excludedGroups>
    </configuration>
</plugin>

実行方法

前提条件

- Chromeブラウザがインストール済み
- アプリケーションが起動済み(http://localhost:8080)
- Lombokのjarファイルが`lib`ディレクトリに配置済み

実行手順

#1. Chromeブラウザのバージョン確認

chrome://version にアクセスして確認

#2. テストコマンドの実行

mvn test -Dtest=テスト対象のクラス名 -Dmaven.compiler.classpath=lib/lombok.jar

トラブルシューティング

ChromeDriver?のバージョン互換性エラー

以下の順で対応:

#1. Chromeブラウザを最新版にアップデート
#2. キャッシュされたChromeDriverを削除
- 削除対象ディレクトリ: ~/.cache/selenium
#3. テストを再実行

自動ダウンロードについて

- ChromeDriverは WebDriverManager により自動的にダウンロード
- ただし、Chromeブラウザのバージョンと互換性が必要

テスト箇所にブレークポイントを張りたい場合

実行には、VSCodeのフラスコマークのアイコンでデバッグ実行ができるが。。。

テストの設定についてメモ

Maven Surefireプラグインでテストが実行されない問題の解決方法

問題

Maven Surefireプラグインでテストを実行しようとすると、以下のようなエラーが発生する場合があります:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project xxx: No tests were executed!  (Set -DfailIfNoTests=false to ignore this error.)

原因

解決方法

pom.xmlに以下の設定を追加します:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>3.5.2</version>
  <configuration>
    <includes>
      <include>**/*Test.java</include>
    </includes>
    <failIfNoTests>false</failIfNoTests>
    <useFile>false</useFile>
    <testFailureIgnore>true</testFailureIgnore>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven.surefire</groupId>
      <artifactId>surefire-junit4</artifactId>
      <version>3.5.2</version>
    </dependency>
  </dependencies>
</plugin>

設定の説明

テスト実行コマンド

特定のテストメソッドを実行する場合:

mvn test "-Dtest=クラス名#メソッド名"

例:

mvn test "-Dtest=xxx.SimpleTest#testAlwaysPass"

全てのテストを実行する場合:

mvn test

注意点

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2025-03-03 (月) 15:21:06 (14d)