文件

§撰寫功能測試

Play 提供許多協助功能測試的類別和便利方法。大多數可以在 play.test 套件或 Helpers 類別中找到。

您可以透過匯入下列內容來新增這些方法和類別

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

§建立 應用程式 實例進行測試

Play 經常需要執行中的 應用程式 作為內容。為了提供測試環境,Play 提供了產生新的應用程式實例進行測試的輔助程式

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

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

§注入測試

如果您使用 Guice 進行 相依性注入,則可以 直接建立 應用程式進行測試。您也可以注入測試類別中您可能需要的任何成員。通常最佳做法是僅在功能測試中注入成員,並在單元測試中手動建立實例。

@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);
}

§使用應用程式進行測試

若要使用 應用程式 執行測試,您可以執行下列動作

@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 建立的 應用程式 執行測試,您可以執行下列動作

@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 進行測試時,有不同的方式可以自訂 應用程式 建立。

§透過路由測試控制器動作

使用執行中的應用程式,您可以從路由路徑中擷取動作參考並呼叫它。這也允許您使用 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());
}

注意:反向路由器不會執行動作,而是只提供包含資訊的 Call,此資訊將用於建立 RequestBuilder,並稍後使用 Helpers.route(Application, RequestBuilder) 呼叫動作本身。這就是為什麼在測試中使用反向路由器建立 Http.RequestBuilder 時,即使動作將 Http.Request 作為參數接收,也不需要傳遞 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://127.0.0.1:" + port;
    } else {
      port = testServer.getRunningHttpPort().getAsInt();
      url = "https://127.0.0.1:" + 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();
    }
  }
}

§使用瀏覽器進行測試

如果您想要使用網頁瀏覽器測試應用程式,您可以使用 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 進行測試


在此文件發現錯誤?此頁面的原始程式碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時貢獻一個 pull request。有問題或建議要分享?前往 我們的社群論壇 與社群展開對話。