CLOVER🍀

That was when it all began.

Spring Boot/Spring Frameworkのテストに関するドキュメントをざっくり眺めてみる

これは、なにをしたくて書いたもの?

Springに関するテストの話について、あまり知らないのでちょっと見ておこうかな、と思いまして。

さらっと、Springのテストに関するドキュメントを眺めてみます。

Springのテストに関する話

今回扱うのは、Spring Bootのテストに関する話とSpring Frameworkのテストに関する話(Spring Test)について見ていこうかなと思います。

対象のバージョンは、以下とします。

Spring Bootのテストに関するドキュメントはこちら。

Core Features / Testing

Spring Frameworkのテスト(Spring Test)に関するドキュメントは、こちら。

Testing

それぞれ見ていきますが、今回は単体テストについて

Spring Bootとテスト

まずは、Spring Bootに関するテストについて、見ていきます。

Core Features / Testing

こちらのドキュメントは、4つのセクションに分かれています。

注目して読むべきは、Springアプリケーションのテストに関する話と、Spring Bootアプリケーションに関するテストの話ですね。

ところで、Test Scope DependenciesのSpring Testの箇所には、以下のように書かれています。

Spring Test & Spring Boot Test: Utilities and integration test support for Spring Boot applications.

テストのユーティリティと、Spring Bootアプリケーションのインテグレーションテストをサポートするものだ、と書かれていますね。

また、 Core Features / Testing / Testing Spring Applications を見ると、以下のように書かれています。

One of the major advantages of dependency injection is that it should make your code easier to unit test. You can instantiate objects by using the new operator without even involving Spring. You can also use mock objects instead of real dependencies.

Springを使わず、new演算子を使ったインスタンス化、そしてモックを利用して単体テストができるということが書かれています。

SpringのApplicationContextやSpring Test、Spring Boot Testを使うのはインテグレーションテストであるとも書かれています。

Often, you need to move beyond unit testing and start integration testing (with a Spring ApplicationContext).

The Spring Framework includes a dedicated test module for such integration testing. You can declare a dependency directly to org.springframework:spring-test or use the spring-boot-starter-test “Starter” to pull it in transitively.

つまり、Springのテストに関する機能は、インテグレーションテストを対象にしていることになります。

Spring Frameworkとテスト

ここで、Spring Frameworkのテストに関するドキュメントを見てみます。

Testing

このドキュメントは、主に次の2つの内容で構成されています。

ドキュメントの冒頭を見ると、このページは単体テストのベストプラクティスとSpringのインテグレーションテストに関するサポートに
ついて書いてある、との記載があります。

This chapter covers Spring’s support for integration testing and best practices for unit testing.

ここでも、Spring Frameworkの提供する機能の多くはインテグレーションテスト向けのものだということになりますね。

Spring Frameworkと単体テスト

Spring Frameworkのテストに関する話題はインテグレーションテストに関するものだということはわかりましたが、単体テストのセクションも
ありましたね。こちらも追ってみましょう。

Testing / Unit Testing

このセクションの冒頭を見ると、以下のようなことが書かれています。

  • POJOは、Springやその他のコンテナを使用せずにnew演算子でインスタンス化し、JUnitなどでテストできるようにすべきだ
  • コードの分離は、モックを使って実現可能
  • Springは、単体テスト向けのモックオブジェクトとテストサポートを提供する

基本的には単体テストはSpringを使わずに実行できるべきであり、ランタイムのセットアップが不要になるので単体テストは高速に
実行されることを期待しています。

True unit tests typically run extremely quickly, as there is no runtime infrastructure to set up. Emphasizing true unit tests as part of your development methodology can boost your productivity.

とはいえ、単体テスト向けのSpringのサポートもある、という話のようです。

提供されるのは、以下ですね。

  • モックオブジェクト
    • Environment
      • org.springframework.mock.envパッケージに含まれるモック実装
      • MockEnvironment、MockPropertySource
    • JNDI
      • org.springframework.mock.jndiパッケージに含まれるモック実装
      • ただし非推奨化されており、Simple-JNDI等で代替される
    • Servlet API
      • org.springframework.mock.webパッケージに含まれるモック実装
    • Spring Web Reactive
      • org.springframework.mock.http.server.reactiveパッケージに含まれるモック実装
  • 単体テストサポート
    • General Testing Utilities
      • org.springframework.test.utilパッケージに含まれるユーティリティ
      • リフレクションのユーティリティReflectionTestUtils、AOP関連のユーティリティAopTestUtilsなど
    • Spring MVC Testing Utilities
      • org.springframework.test.webパッケージに含まれるユーティリティ
      • Controllerのテストを行うには、ModelAndViewAssertなどを使い、Servlet APIのモック(MockHttpServletRequestやMockHttpSessionと組み合わせる

Spring Frameworkとインテグレーションテスト

Spring Frameworkのテストに関するドキュメントには単体テストとインテグレーションテストの内容が書かれているわけですが、
ページ内のボリュームを見ると大半はインテグレーションテスト向けのものであることがわかります。

このセクションの概要を見てみます。

Testing / Integration Testing / Overview

It is important to be able to perform some integration testing without requiring deployment to your application server or connecting to other enterprise infrastructure.

アプリケーションサーバーへのデプロイや、他のエンタープライズインフラストラクチャーへの接続なしにインテグレーションテストを
実行できることを重要視しています。

これで、主にSpringのコンテキストを正しく構築できているか、データベースアクセスなどをテストできる、としています。

このセクションで書かれているSpring Test(spring-test)のorg.springframework.testパッケージには、Springのコンテナを使った
インテグレーションテストに関するクラスが含まれています。

これらを使用したテストはアプリケーションサーバーやその他の環境に依存しておらず、単体テストよりは遅いものの、アプリケーションサーバーに
デプロイしてのSeleniumでのテストやリモートテストよりもずっと高速です。

Springにおける、インテグレーションテストの目標は以下に書かれています。

Testing / Integration Testing / Goals of Integration Testing

こういった感じですね。

また、以下の機能が含まれています。

Spring Bootアプリケーションのテスト

ところで、Spring Bootのテストに関するセクションには、次の2つが含まれていました。

Springアプリケーションのテストは、先ほどまで書いていたSpring Testの話です。

ではSpring Bootアプリケーションのテストに関する話は?というと、Spring BootアプリケーションもSpringアプリケーションであるため、
特別なことはないと書かれています。

A Spring Boot application is a Spring ApplicationContext, so nothing very special has to be done to test it beyond what you would normally do with a vanilla Spring context.

ですが、いくつかの機能は提供するようです。以下に一部を記載しますが、基本的にはAuto Configurationに関する機能のようですね。

  • Detecting Web Application Type
    • Spring Web MVCが利用可能な場合はMVCベースのApplicationContextを構築し、Spring WebFluxのみが利用可能な場合はWebFluxベースのApplicationContextを構築する
  • Detecting Test Configuration
    • Spring Bootの@*Testアノテーションを使用することで、プライマリーの構成を明示しない場合は自動構成を行う
  • Testing with a mock environment
    • モックサーバーでのテスト
  • Testing with a running server
    • 実際のサーバーを起動してのテスト
  • Customizing WebTestClient
    • WebTestClientのカスタマイズ
  • Mocking and Spying Beans
    • Beanのモックおよびスパイ
  • Auto-configured Tests
    • Spring BootのAuto Configurationをカスタマイズし、部分的にAuto Configurationを使うための多数のスライスおよびテスト
    • 使い方は同セクションに書かれているが、別ページのTest Auto-configuration Annotationsに、各スライスに含まれるAuto Configurationが記載されている
  • Test Utilities
    • いくつかのテストユーティリティ(ConfigDataApplicationContextInitializer、TestPropertyValues、OutputCapture、TestRestTemplate
  • Creating Your Own Auto-configuration
    • 独自のAuto Configurationのサポート

まとめ

Springのテストに関するドキュメントを見て、Springのテストのサポートに対する考え方や、カバーするフェーズ(単体テスト、
インテグレーションテスト)、どのような機能が提供するかをざっくり眺めてみました。

雰囲気はおよそわかったので、そのうちいくつかの機能を使ってテストに関する勉強をしていきたいですね。