§撰寫功能測試
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。有問題或建議要分享?前往 我們的社群論壇 與社群展開對話。