Please read Testing In Chromium for general guidance on writing tests in chromium.
The following tests are expected for writing code in this system:
WebContents
functionality, as that is not built as part of unit test frameworks. Instead, they must use the FakeWebAppUrlLoader
or FakeWebAppDataRetriever
classes.PRE_
test functionality to set up any state.Unit tests have the following benefits:
Unit tests are the fastest tests to execute and are expected to be used to test most cases, especially error cases. They are usually built on the WebAppTest
base class, and use the FakeWebAppProvider
to customize (or not) the dependencies of the WebAppProvider
system.
Notes
WebAppTest
base class if possible.WebAppTest
print a snapshot of chrome://web-app-internals to console on test failures. This can be a powerful debugging tool. The command line flag --disable-web-app-internals-log
can be used to disable this feature.With improved web app test support, most of the components should using unittests to cover the detailed test cases.
Creating an integration test (using the integration framework) should satisfy the need for end-to-end tests for major use-cases of your feature. However, you may need to create one due to:
Browser tests are much more expensive to run, as they run a fully functional browser. These tests are usually only created to test functionality that requires multiple parts of the system to be running or dependencies like the Sync service to be fully running and functional. It is good practice to have browsertests be as true-to-user-action as possible, to make sure that as much of our stack is exercised.
An example set of browser tests are in web_app_browsertest.cc
. Please use the WebAppBrowserTestBase
base class.
Notes
WebAppBrowserTestBase
print a snapshot of chrome://web-app-internals to console on test failures. This can be a powerful debugging tool. The command line flag --disable-web-app-internals-log
can be used to disable this feature.We have a custom integration testing framework that we use due to the complexity of our use-cases. See integration-testing-framework.md for more information.
It is a good idea to think about your integration tests early & figure out your CUJs with the team. Having your CUJs and integration tests working early greatly speeds up development & launch time.
Notes
WebAppIntegrationTestDriver
print a snapshot of chrome://web-app-internals to console on test failures. This can be a powerful debugging tool. The command line flag --disable-web-app-internals-log
can be used to disable this feature.It is very common to test OS integration. By default, OS integration is suppressed if the test extends WebAppTest
or WebAppBrowserTestBase
.
End-to-end OS integration testing is facilitated using the OsIntegrationTestOverride
. If OS integration CAN be tested in an automated way, this class will do so. If not, the existence of this override will stub-out the OS integration at the lowest level to test as much of our code as possible.
Fake*
classesA class that starts with Fake
is meant to completely replace a component of the system. They inherit from a base class with virtual methods, and allow a test to specify custom behavior or checks. The component should seem to be working correctly to other system components, but with behavior that is defined by a test.
The most common pattern here is that the Fake will by default appear to work correctly, and a test can either specify it to return custom results, fail in specific ways, or simply check that it was used in the correct way.
An example is fake_os_integration_manager.h, which pretends to successfully perform install, update, and uninstall operations on OS integration, but instead pretends to work and does simple bookkeeping for tests to check that it was called correctly.
Mock*
classesA class that start with Mock
is a gmock version of the class. This allows the user to have complete control of exactly what that class does, verify it is called exactly as expected, etc. These tend to be much more powerful to use than a Fake
, as you can easily specify every possible case you might want to check, like which arguments are called and the exact calling order of multiple functions, even across multiple mocks. The downsides are:
These are generally not preferred to a “Fake”.
FakeWebAppProvider
The FakeWebAppProvider
is basically a fake version of the WebAppProvider system, that uses the WebAppProvider
root class to set up subsystems and can be used to selectively set fake subsystems or shut them down on a per-demand basis to test system shutdown use-cases.
By default, the FakeWebAppProvider
will NOT start the WebAppProvider
system, and it must be manually done so. This is usually done by calling AwaitStartWebAppProviderAndSubsystems
.
Many operations that happen at higher levels that the commands / scheduling system in the WebAppProvider require that tests wait for async operations to complete.
AllBrowserTabAddedWaiter
- Waits for a tab to be added anywhere (works for both app browser and regular browser).BrowserChangeObserver
- Waits for a browser to add or remove.UrlLoadObserver
- Waits for given url to load anywhere.content::TestNavigationObserver
- Waits for a navigation anywhere or in given WebContents. See StartWatchingNewWebContents to watch all web contents.content::WebContentsObserver
- Can generally be used to wait for events on a given content::WebContents
onload
to complete in a page, the ::DocumentOnLoadCompletedInPrimaryMainFrame
can be used if WebContents::IsDocumentOnLoadCompletedInPrimaryMainFrame()
returns false.WebAppProvider
commandsWebAppCommandManager::AwaitAllCommandsCompleteForTesting
will wait for all commands to complete. This will mostly handle all tasks in the WebAppProvider
.
Sometimes classes use a dependency that either doesn‘t work or isn’t fake-able in our system.
KeyedService
, and the authors have a fake version you can use, then use that. See how it is used elsewhere.WebAppProvider
, and create a fake for it so that you can test with it faked.