ドキュメント

§機能テストの記述

Playは、機能テストを支援する多くのクラスと便利なメソッドを提供しています。これらのほとんどは、play.testパッケージまたはHelpersクラスにあります。

以下のインポートにより、これらのメソッドとクラスを追加できます。

import play.test.*;
import static play.test.Helpers.*;

§テスト用のApplicationインスタンスの作成

Playは、コンテキストとして実行中のApplicationを頻繁に必要とします。テスト環境を提供するために、Playはテスト用の新しいアプリケーションインスタンスを生成するヘルパーを提供しています。

import static play.test.Helpers.*;
Application fakeApp = fakeApplication();

Application fakeAppWithMemoryDb = fakeApplication(inMemoryDatabase("test"));

§テストの注入

依存性注入にGuiceを使用している場合、テスト用のApplication直接ビルドできます。必要なテストクラスのメンバーを注入することもできます。一般的に、メンバーの注入は機能テストのみで行い、ユニットテストでは手動でインスタンスを作成することをお勧めします。

@Inject Application application;

@Before
public void setup() {
  Module testModule =
      new AbstractModule() {
        @Override
        public void configure() {
          // Install custom test binding here
        }
      };

  GuiceApplicationBuilder builder =
      new GuiceApplicationLoader()
          .builder(new Context(Environment.simple()))
          .overrides(testModule);
  Guice.createInjector(builder.applicationModule()).injectMembers(this);

  Helpers.start(application);
}

@After
public void teardown() {
  Helpers.stop(application);
}

§アプリケーションを使ったテスト

Applicationを使用してテストを実行するには、次のようにします。

@Test
public void findById() {
  running(
      fakeApplication(inMemoryDatabase("test")),
      () -> {
        Computer macintosh = Computer.findById(21l);
        assertEquals("Macintosh", macintosh.name);
        assertEquals("1984-01-24", formatted(macintosh.introduced));
      });
}

WithApplicationを拡張することもできます。これにより、各テストメソッドに対してアプリケーションが自動的に起動および停止されます。

public class FunctionalTest extends WithApplication {

§Guiceアプリケーションを使ったテスト

Guiceによって作成されたApplicationでテストを実行するには、次のようにします。

@Test
public void findById() {
  ClassLoader classLoader = classLoader();
  Application application =
      new GuiceApplicationBuilder()
          .in(new Environment(new File("path/to/app"), classLoader, Mode.TEST))
          .build();

  running(
      application,
      () -> {
        Computer macintosh = Computer.findById(21l);
        assertEquals("Macintosh", macintosh.name);
        assertEquals("1984-01-24", macintosh.introduced);
      });
}

Guiceを使用してテストする場合、Applicationの作成をカスタマイズする方法はいくつかあります。

§ルーティングを介したコントローラーアクションのテスト

実行中のアプリケーションでは、ルートのパスからアクション参照を取得して呼び出すことができます。これにより、偽のリクエストを作成するRequestBuilderを使用することもできます。

import play.mvc.Http.RequestBuilder;
@Test
public void testBadRoute() {
  RequestBuilder request = Helpers.fakeRequest().method(GET).uri("/xx/Kiwi");

  Result result = route(app, request);
  assertEquals(NOT_FOUND, result.status());
}

リバースルーターを使用して直接RequestBuilderを作成し、ルーターパスをハードコーディングすることも避けることができます。

@Test
public void testGoodRouteCall() {
  RequestBuilder request = Helpers.fakeRequest(routes.HomeController.index());

  Result result = route(app, request);
   assertEquals(OK, result.status());
}

**注意:** リバースルーターはアクションを実行するのではなく、RequestBuilderの作成に使用され、後でHelpers.route(Application, RequestBuilder)を使用してアクション自体を呼び出す情報を含むCallを提供するだけです。そのため、アクションがパラメーターとしてHttp.Requestを受け取っている場合でも、テストでリバースルーターを使用してHttp.RequestBuilderを作成するときにHttp.Requestを渡す必要はありません。

§サーバーを使ったテスト

テスト内から実際のHTTPスタックをテストしたい場合があります。これは、テストサーバーを起動することで実行できます。

@Test
public void testInServer() throws Exception {
  TestServer server = testServer(3333);
  running(
      server,
      () -> {
        try (WSClient ws = WSTestClient.newClient(3333)) {
          CompletionStage<WSResponse> completionStage = ws.url("/").get();
          WSResponse response = completionStage.toCompletableFuture().get();
          assertEquals(OK, response.getStatus());
        } catch (Exception e) {
          logger.error(e.getMessage(), e);
        }
      });
}

WithApplicationクラスがあるのと同様に、WithServerクラスもあり、これを拡張してテスト用にTestServerを自動的に起動および停止できます。

public class ServerFunctionalTest extends WithServer {

  @Test
  public void testInServer() throws Exception {
    OptionalInt optHttpsPort = testServer.getRunningHttpsPort();
    String url;
    int port;
    if (optHttpsPort.isPresent()) {
      port = optHttpsPort.getAsInt();
      url = "https://localhost:" + port;
    } else {
      port = testServer.getRunningHttpPort().getAsInt();
      url = "http://localhost:" + port;
    }
    try (WSClient ws = play.test.WSTestClient.newClient(port)) {
      CompletionStage<WSResponse> stage = ws.url(url).get();
      WSResponse response = stage.toCompletableFuture().get();
      assertEquals(NOT_FOUND, response.getStatus());
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

§ブラウザを使ったテスト

Webブラウザからアプリケーションをテストする場合は、Selenium WebDriverを使用できます。 PlayはWebDriverを起動し、FluentLeniumによって提供される便利なAPIでラップします。

@Test
public void runInBrowser() {
  running(
      testServer(),
      HTMLUNIT,
      browser -> {
        browser.goTo("/");
        assertEquals("Welcome to Play!", browser.el("#title").text());
        browser.$("a").click();
        assertEquals("login", browser.url());
      });
}

もちろん、各テストでブラウザを自動的に開閉するWithBrowserクラスもあります。

public class BrowserFunctionalTest extends WithBrowser {

  @Test
  public void runInBrowser() {
    browser.goTo("/");
    assertNotNull(browser.el("title").text());
  }
}

**次へ:** Guiceを使ったテスト


このドキュメントに誤りを見つけましたか? このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを送信してください。質問やアドバイスがありましたら、コミュニティフォーラムにアクセスして、コミュニティとの会話を始めてください。