Java
Selenium
spring
spring-boot

Spring+Seleniumでファイルアップロード画面をテストする方法

More than 1 year has passed since last update.

Springbootで作ったアップロード画面に対してseleniumでテストコード書いてみると、
ファイル選択ダイアログが操作できずにテストが出来なかったのでそれを解消する方法を下記に記載します。

※もし他にいい方法があればご意見お待ちしております!

実現方法

seleniumでは<input type='file'>の操作が難しいため、
サーバ側(Java側)でfile属性に対して自動的にファイルを設定するようにした。

実装ポイント

  1. ControllerAdviceCustomクラスで画面から受け取るパラメータに対しての拡張ポイントを追加
  2. MockFileEditorクラスを作成してMockMultipartFileを生成して設定する処理を追加
  3. テスト実行時にControllerAdviceCustomクラスの拡張ポイントに対して、型がMultipartFileの場合はMockFileEditorクラスを通すように設定

これでselenium側で<input type='file'>の操作に悩まされることがなくなって一安心!

ControllerAdviceCustom.java
@ControllerAdvice
public class ControllerAdviceCustom {
    @InitBinder
    public void initBinderMock(WebDataBinder dataBinder) {
        // Mock拡張ポイント(実装はテスト側でMockUpを使用)
    }

    // 以下省略
}
MockFileEditor.java
public class MockFileEditor extends PropertyEditorSupport {
    @Override
    public void setValue(Object obj) {
        // パラメータ(Multipart)対してMockMultipartFileを生成して反映
        String textFile = "dummy text file";
        MultipartFile mockFile = new MockMultipartFile("file", textFile.getBytes());
        super.setValue(mockFile);
    }
}
SeleniumTest.java
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SeleniumTest {

    @Before
    public void setup() {
        // ControllerAdviceCustomクラスのモック拡張ポイントを実装
        new MockUp<ControllerAdviceCustom>() {
            @Mock
            @InitBinder
            public void initBinderMock(WebDataBinder dataBinder) {
                // 型がMultipartFileの場合はMockFileEditorクラスを通すように設定
                dataBinder.registerCustomEditor(MultipartFile.class, new MockFileEditor());
            }
        };
    }

    @Test
    public void ファイルアップロードを含む画面のテスト() {
        // 以下省略
    }
}

補足

調べてみるとseleniumでも<input type='file'>の操作は可能らしいです。
ただしその手段が全てのブラウザで可能かどうかが怪しい&ブラウザのバージョンアップ(セキュリティ対策)によって使えなくなる可能性があったので今回の実現方法にしました。