趣旨

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

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

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

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

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

背景

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

環境構築

必要な依存関係

pom.xmlに以下の依存関係を追加する: selenium-java junit-jupiter webdrivermanager

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

UTF-8 UTF-8 1.8 1.18.36 4.18.0 5.10.2 3.25.3 5.7.0

依存を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

テストの実行制御

org.apache.maven.plugins maven-surefire-plugin selenium

実行方法

前提条件

- 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.)

原因

  • maven-surefire-pluginのバージョンが古い(2.22.2など)
  • JUnit 4のテストを実行するための適切な設定がない

解決方法

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>

設定の説明

  • version: 最新バージョン(2025年3月時点では3.5.2)に更新
  • includes: テストファイルのパターンを指定
  • failIfNoTests: テストが見つからない場合にビルドを失敗させない
  • useFile: テスト結果をコンソールに直接出力
  • testFailureIgnore: テスト失敗時もビルドを続行
  • dependencies: JUnit 4用の依存関係(surefire-junit4)を追加

テスト実行コマンド

特定のテストメソッドを実行する場合: mvn test "-Dtest=クラス名#メソッド名"

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

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

注意点

  • コマンドラインでパラメータを指定する際は、Windowsのcmdでは引用符(")で囲む必要がある
  • 文字化けが発生する場合は、UTF-8エンコーディングを指定する("-Dfile.encoding=UTF-8")

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   最終更新のRSS
Last-modified: 2025-03-03 (月) 15:21:06