Play provides a number of classes and convenience methods that assist with functional testing. Most of these can be found either in the play.api.test package or in the Helpers object. The ScalaTest + Play integration library builds on this testing support for ScalaTest.

You can access all of Play’s built-in test support and ScalaTest + Play with the following imports:

Play frequently requires a running Application as context. Providing an application to a test environment depends on how the application is built. If you’re using the default Guice dependency injection, you can use the GuiceApplicationBuilder class which can be configured with different configuration, routes, or even additional modules.

If all or most tests in your test class need a Application, and they can all share the same instance of Application, mix in trait GuiceOneAppPerSuite with the GuiceFakeApplicationFactory trait. You can access the Application from the app field.

If you need to customize the Application, override fakeApplication() as shown in this example:

The reason ScalaTest + Play provides both GuiceOneAppPerSuite and OneAppPerTest is to allow you to select the sharing strategy that makes your tests run fastest. If you want application state maintained between successive tests, you’ll need to use GuiceOneAppPerSuite. If each test needs a clean slate, however, you could either use OneAppPerTest or use GuiceOneAppPerSuite, but clear any state at the end of each test. Furthermore, if your test suite will run fastest if multiple test classes share the same application, you can define a master suite that mixes in GuiceOneAppPerSuite and nested suites that mix in ConfiguredApp, as shown in the example in the documentation for ConfiguredApp. You can use whichever strategy makes your test suite run the fastest.

Sometimes you want to test with the real HTTP stack. If all tests in your test class can reuse the same server instance, you can mix in OneServerPerSuite (which will also provide a new Application for the suite):

The OneServerPerSuite and OneServerPerTest traits provide the port number on which the server is running as the port field. By default this is 19001, however you can change this either overriding port or by setting the system property testserver.port. This can be useful for integrating with continuous integration servers, so that ports can be dynamically reserved for each build.

You can also customize the Application by overriding app, as demonstrated in the previous examples.

Lastly, if allowing multiple test classes to share the same server will give you better performance than either the OneServerPerSuite or OneServerPerTest approaches, you can define a master suite that mixes in OneServerPerSuite and nested suites that mix in ConfiguredServer, as shown in the example in the documentation for ConfiguredServer.

If you want to run tests in multiple web browsers, to ensure your application works correctly in all the browsers you support, you can use traits AllBrowsersPerSuite or AllBrowsersPerTest. Both of these traits declare a browsers field of type IndexedSeq[BrowserInfo] and an abstract sharedTests method that takes a BrowserInfo. The browsers field indicates which browsers you want your tests to run in. The default is Chrome, Firefox, Internet Explorer, HtmlUnit, and Safari. You can override browsers if the default does not fit your needs. You place tests you want to run in multiple browsers in the sharedTests method, placing the name of the browser at the end of each test name. (The browser name is available from the BrowserInfo passed into sharedTests.) Here is an example that uses AllBrowsersPerSuite:

All tests declared by sharedTests will be run with all browsers mentioned in the browsers field, so long as they are available on the host system. Tests for any browser that is not available on the host system will be canceled automatically.

Note: You need to append the browser.name manually to the test name to ensure each test in the suite has a unique name (which is required by ScalaTest). If you leave that off, you’ll get a duplicate-test-name error when you run your tests.

AllBrowsersPerSuite will create a single instance of each type of browser and use that for all the tests declared in sharedTests. If you want each test to have its own, brand new browser instance, use AllBrowsersPerTest instead:

Although both AllBrowsersPerSuite and AllBrowsersPerTest will cancel tests for unavailable browser types, the tests will show up as canceled in the output. To can clean up the output, you can exclude web browsers that will never be available by overriding browsers, as shown in this example:

In all the test classes shown in previous examples, all or most tests in the test class required the same fixtures. While this is common, it is not always the case. If different tests in the same test class need different fixtures, mix in trait MixedFixtures. Then give each individual test the fixture it needs using one of these no-arg functions: App, Server, Chrome, Firefox, HtmlUnit, InternetExplorer, or Safari.

If you are calling a web service, you can use WSTestClient. There are two calls available, wsCall and wsUrl that will take a Call or a string, respectively. Note that they expect to be called in the context of a running application.