きり丸の技術日記

技術・エンジニアのイベント・資格等はこちらにまとめる予定です

【Spring】Spring機能使いつつ、テストを高速化する

※ もっと高速化する方法がありましたら教えていただきたいです。
もしくは、高速化するためのリファレンスページ教えてください。

はじめに

Springフレームワークは、DI機能を持っており、依存関係を疎にできます。
テストするときは、@SpringBootTestのアノテーションを使用すれば依存関係を解決しつつ、対象テストクラスを生成できます。

非常に便利ではありますが、デフォルトで@SpringBootTestを使用している場合、対象テストに不要なファイルまでDIしてしまいます。

規模が小さいうちはいいのですが、Repositoryのテストをしたいのに、ControllerやServiceのテストまでDIしていると無視できない速度になってきます。

そこで必要なクラス、パッケージだけダウンロードする方法を探しましたので、使ってみてください。

Controller層でのテスト

WebMvcTestを使用します。

@WebMvcTest(DefultController.class) // 対象のクラスのみDIする
class DefultControllerTests {
    @Autowired
    private MockMvc mockMvc;
    private final String rootUrl = "/index";

    @Test
    void test_01() throws Exception {
        this.mockMvc.perform(get(rootUrl))
                .andExpect(status().is5xxServerError())
        ;
    }
}

Service層でのテスト

DI対象のクラスを指定する

※ SpringJunitConfigでも行けるかと思いましたが、思ったよりもローカルで速度が出ませんでした。

なので、SpringBootTestで直接class指定する方法をとっています。

@SpringBootTest(classes = DateConverter.class)
class SpringJunitConfigTest {
  @Autowired
  DateConverter target;

  @Test
  void test_01() {
    LocalDateTime now = LocalDateTime.of(2019, 8, 1, 1, 1);
    assertThat(target.now()).isAfter(now);
  }
}

DI対象のパッケージを指定する

// 自分のクラスにConfigファイルを設定する
@SpringJUnitConfig(SpringJunitConfigTest.Config.class)
class SpringJunitConfigTest {
    @Autowired
    DateConverter target;

    // DIしたいパッケージを指定する
    @ComponentScan({"jp.co.kelly.biz.domain"})
    static class Config {
    }

    @Test
    void test_01() {
        LocalDateTime now = LocalDateTime.of(2019, 8, 1, 1, 1);
        assertThat(target.now()).isAfter(now);
    }
}

Repository層でのテスト

ライブラリが提供している専用のテストアノテーションを使用します。
MyBatisTestやFlywayTestがそれにあたります。

FlywayTestは毎回Flywayのマイグレーションファイルを実行するので、できればMyBatisTestを使用したほうがいいです。

職場はそうしているのですが、自宅でMyBatisの素振りはしてなかったので、紹介だけに留めさせてください。

終わりに

自分のGithubはほとんど素振り用なので、高速化の効果が期待できるだけのプロジェクトがありません。
なので、具体的にどの程度速度UPが見込めるかがわかりません。
職場では明らかに早くはなったのですが…。


こういう、高速化の技術ってどうすれば身につきますかね。

必要なファイルだけ読み込むようにする

ということが大事なのはわかりましたが、それに対する設定はまだまだ苦手です。

QAエンジニアってこういうスキルも求められると考えています。
なので、QAエンジニアとしての道を考えていくなら、もっとこのスキルを伸ばしていきたいです。


もしこの記事が役に立ったのであれば、はてぶ、Twitterでの記事の拡散、twitterのフォローもよろしくお願いします。

参考資料

Difference between using MockMvc with SpringBootTest and Using WebMvcTest

stackoverflow.com